Как издеваться над ModelMapper весной? - PullRequest
1 голос
/ 12 апреля 2020

Я пытаюсь написать модульный тест для моего сервисного слоя:

@SpringBootTest
class ClinicServiceTest {

@Mock
private ProcedureRepository procedureRepository;
@InjectMocks
private ClinicService clinicService;

@Test
void setProcedureStatus() {
    when(procedureRepository.findById(1L)).thenReturn(Optional.of(initialEntity));
    when(procedureRepository.saveAndFlush(expectedEntity)).thenReturn(expectedEntity);
    Procedure assertProcedure = clinicService.setProcedureStatus(1L, "CANCELED");
  }
}

Когда я вызываю setProcedureStatus метод, он генерирует исключение NullPointerException, потому что мой класс обслуживания использует ModelMapper, который автоматически подключается Spring:

@Service
@RequiredArgsConstructor
public class ClinicService {

private final ProcedureRepository procedureRepository;
private final ModelMapper modelMapper;

public Procedure setProcedureStatus(Long procedureId, String status) {
    ...
    return modelMapper.map(procedureEntity, Procedure.class);
}

}

Модульный тест не поднимает контекст Spring, поэтому ModelMapper не имеет значения в Service, когда я вызываю его из теста. Есть ли способы решить эту проблему?

1 Ответ

3 голосов
/ 12 апреля 2020

Вы хотите написать модульный тест, чтобы вы не поднимали контекст пружины. Модульные тесты являются самыми быстрыми, чем интеграционные тесты (где вы часто хотите поднять свой весенний контекст). Когда дело доходит до модульных тестов, вы хотите протестировать unit часть вашего приложения.

В этом случае вы получаете NPE, потому что вы не инициализировали ModelMapper.

Я не видел, где вы создаете свой ClinicService, но есть один пример того, как вы можете избежать этого NPE:

@Test
void setProcedureStatus() {
    when(procedureRepository.findById(1L)).thenReturn(Optional.of(initialEntity));
    when(procedureRepository.saveAndFlush(expectedEntity)).thenReturn(expectedEntity);
    // Initialize ClinicService with mocked procedeRepository but real ModelMapper
    ClinicService clinicService = new ClinicService(procedureRepository, new ModelMapper(), ... other dependencies );
    Procedure assertProcedure = clinicService.setProcedureStatus(1L, "CANCELED");
}

или вы можете также высмеивать ModelMapper.

Другим способом является использование MockitoJunitRunner и инициализация вашего класса в тестах, как показано ниже:

@RunWith(MockitoJUnitRunner.class)
 public class ExampleTest {

     @Mock
     private ModelMapper modelMapper;

     @Mock
     private Repository repository;

     @InjectMocks
     private ClinicService classUnderTest;

Благодаря внедрению зависимостей ваш код гораздо проще тестировать, поскольку вы можете просто создать свой сервис с зависимостями прошло через конструктор.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...