#java #spring #spring-boot #mocking #spring-test
#java #весна #весенняя загрузка #издевательство #spring-test
Вопрос:
У меня очень плохая реализация компонента
@Component
public class Repository{
public List<String> people= new ArrayList<>();
И у меня также есть тест, в котором я заменяю репозиторий макетом.
Но когда я пытаюсь получить доступ к полю «люди» в тесте через макет репозитория, я получаю исключение NullPointerException
@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class MainControllerTest{
@Autowired
private MockMvc mockMvc;
@MockBean
private Repository repository;
@Test
public void someTest(){
repository.people // null -> NullPointerException
}
}
Почему это происходит? Инициализирован ли компонент изначально или нет? Каково правильное решение при такой плохой реализации?
Ответ №1:
Компонент инициализируется так, как он должен быть @MockBean
. Для вас создается только заглушка. Все вложенные элементы Repository
класса игнорируются. В вашем случае у вас есть полностью инициализированный макет. Но, конечно, вложенные поля имеют значение null. Потому что это макет, и вложенные поля не будут инициализированы. Mock предполагает, что вам просто нужна какая-то оболочка этого конкретного класса, чтобы имитировать какое-то поведение.
Что вам нужно сделать, так это перейти @MockBean
на @SpyBean
. В этом случае поля вашего класса будут инициализированы так, как они определены в вашем Repository
классе. Итак, у вас будет реальный Repository
объект, но завернутый с помощью Mockito Spy. И это позволит вам выполнять все необходимые манипуляции с этим объектом.