@RestController
public class StackOverFlowController {
private StackOverFlowService service;
@Autowired
public StackOverFlowController(
@Qualifier(value = "stackOverFlowServiceImpl")
StackOverFlowService service) {
this.service = service;
}
@RequestMapping("api/stackoverflow")
public List<StackOverFlowDto> getListOfProviders() throws URISyntaxException {
List<StackOverFlowDto> allSites = service.getAllSites();
return allSites;
}
}
public interface StackOverFlowService {
List<StackOverFlowDto> getAllSites() throws URISyntaxException;
List<StackOverFlowDto> getAllSitesByTitle(String title) throws URISyntaxException;
}
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>${version.mapstruct}</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>29.0-jre</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
@RunWith(MockitoJUnitRunner.class)
public class StackOverFlowControllerTest {
@Mock
private StackOverFlowService service ;
@InjectMocks
private StackOverFlowController controller;
@Test
public void getListOfProviders() throws URISyntaxException {
List<StackOverFlowDto> allSites = service.getAllSites();
when(service.getAllSites()).thenReturn(ImmutableList.of());
List<StackOverFlowDto> listOfProviders = controller.getListOfProviders();
verify(service).getAllSites();
}
}
Я могу создать mock-объект следующим образом::
private StackOverFlowService service = Mockito.mock(StackOverFlowService.class);
обновить 1
update 2
Wnen I have done this:
@RunWith(SpringRunner.class)
@WebMvcTest(StackOverFlowController.class)
public class StackOverFlowControllerTest {
@Mock
private StackOverFlowService service;
@InjectMocks
StackOverFlowController controller;
@Test
public void getListOfProviders() throws URISyntaxException {
List<StackOverFlowDto> allSites = service.getAllSites();
when(service.getAllSites()).thenReturn(ImmutableList.of());
List<StackOverFlowDto> listOfProviders = controller.getListOfProviders();
verify(service).getAllSites();
}
}
Я получил ошибку:
PM org.junit.vintage.engine.descriptor.RunnerTestDescriptor warnAboutUnfilterableRunner ПРЕДУПРЕЖДЕНИЕ: Runner org.junit.internal.runners.ErrorReportingRunner (используется в классе com.spring.mon go .web.contollers.stackoverflow.StackOverFlowControllerTest) не поддерживает фильтрацию и поэтому будет выполняться полностью. org.junit.runners.model.InvalidTestClassError: Недействительный тестовый класс com.spring.mon go .web.contollers.stackoverflow.StackOverFlowControllerTest ':
- Нет запускаемых методов
where is the method get() from ?
update 3
This the test was performed:
@WebMvcTest(StackOverFlowController.class)
public class StackOverFlowControllerTest {
@Autowired
private MockMvc mockMvc;
@MockBean
private StackOverFlowService service;
@MockBean
private StackOverFlowController controller;
@Test
public void getListOfProviders() throws Exception {
when(service.getAllSites()).thenReturn(ImmutableList.of());
List<StackOverFlowDto> listOfProviders = controller.getListOfProviders();
assertNotNull(listOfProviders);
}
}
Но я не вижу в этом смысла. Я не получаю никаких данных:
List<StackOverFlowDto> listOfProviders = controller.getListOfProviders();
- Но здесь я должен получить набор элементов, но получаю 0
Обновление 4
Насколько я понимаю:
when(service.getAllSites()).thenReturn(ImmutableList.of());
Тестируем контроллер. Нижние слои нам не нужны. Нам нужно проверить, что вызывается метод
- getListOfProviders () контроллера. Итак,
- service.getAllSites () здесь мы указываем Mockito-object
@MockBean
private StackOverFlowService service;
Этот метод должен возвращать какую-то коллекцию.
thenReturn(ImmutableList.of())
it должен возвращать пустую коллекцию.
Почему?
Я этого не понимаю.
List<StackOverFlowDto> listOfProviders = controller.getListOfProviders();
Для чего это?
Обновить 5
@Test
public void getListOfProviders() throws Exception {
when(service.getAllSites()).thenReturn(ImmutableList.of());
List<StackOverFlowDto> listOfProviders = controller.getListOfProviders();
assertNotNull(listOfProviders);
verify(service).getAllSites();
}
- verify (сервис) .getAllSites (); Это должно подтвердить, что метод getAllSites () из интерфейса StackOverFlowService (из его реализации) вызовет ...
Но снова я получил ошибки:
Требуется, но не вызывается: com.spring.mon go .service.read.stackoverflow.StackOverFlowService # 0 bean.getAllSites (); -> at com.spring.mon go .web.contollers.stackoverflow.StackOverFlowControllerTest.getListOfProviders (StackOverFlowControllerTest. java: 38) На самом деле, с этим макетом не было никаких взаимодействий.
Требуется, но не вызывается : com.spring.mon go .service.read.stackoverflow.StackOverFlowService # 0 bean.getAllSites (); -> at com.spring.mon go .web.contollers.stackoverflow.StackOverFlowControllerTest.getListOfProviders (StackOverFlowControllerTest. java: 38) На самом деле, с этим макетом не было никаких взаимодействий.
Почему ?
Обновление 6
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = {SpringMongoApplication.class})
@WebMvcTest(StackOverFlowController.class)
class StackOverFlowControllerTestUnit {
@Autowired
private MockMvc mockMvc;
@MockBean
private StackOverFlowService service;
@MockBean
private StackOverFlowController controller;
@Test
void getListOfProviders() throws Exception {
MockHttpServletRequestBuilder requestBuilder =
MockMvcRequestBuilders
.get("/api/stackoverflow")
.accept(MediaType.APPLICATION_JSON);
mockMvc.perform(requestBuilder)
.andDo(print())
.andExpect(status().isOk())
.andExpect(MockMvcResultMatchers.jsonPath("$.id").exists())
.andDo(print());
}
}
Здесь создаются beans, но я не получаю json ...
.andExpect(MockMvcResultMatchers.jsonPath("$.sites").exists())
.andExpect(MockMvcResultMatchers.jsonPath("$.sites[*].id").isNotEmpty());
Update_7
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = {SpringMongoApplication.class})
@WebMvcTest(StackOverFlowController.class)
public class StackOverFlowControllerTestFromForum {
@Autowired
private MockMvc mockMvc;
@MockBean
private StackOverFlowService service;
@InjectMocks
private StackOverFlowController controller;
@Test
public void getListOfProviders() throws Exception {
MockHttpServletRequestBuilder requestBuilder =
MockMvcRequestBuilders
.get("/api/stackoverflow")
.accept(MediaType.APPLICATION_JSON);
mockMvc.perform(requestBuilder)
.andDo(print())
.andExpect(status().isOk());
}
}
В этой версии кода все bean-компоненты инициализируются без ошибок. @ InjectMocks - Это тоже работает.
Обычное интеграционное тестирование, предлагаемое Spring, просто создает объекты, как если бы приложение работало в производственной среде. Я до сих пор не понимаю, для чего нужны Mock-объекты.
Здесь любые идеи закончены. Я не понимаю, почему это не работает.
Может кто-нибудь объяснить идею работы аннотаций @Mock и @InjectMocks применительно к этому примеру? Есть у кого-нибудь идеи?