Я написал типичный трехслойный API REST Spring Boot и строю тесты для него. Сам API работает нормально, но я сталкиваюсь с проблемами, заставляющими тесты контроллера работать. Возвращаемое тело пусто, потому что объект, возвращаемый уровнем контроллера, является нулевым. Вот основные зависимости в игре.
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.12.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
Я смоделировал служебный уровень, но, похоже, оператор when в тесте не срабатывает, как я ожидал.
Вот сам тест:
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK)
@AutoConfigureMockMvc
public class VehicleControllerTest {
@MockBean
VehicleServiceImpl vService;
@Mock
HttpServletRequest mockRequest;
@Mock
Principal mockPrincipal;
@Autowired
MockMvc mockMvc;
Vehicle vehicle1;
@BeforeEach
public void setUp() throws ItemNotFoundException {
vehicle1 = new Vehicle();
vehicle1.setVin("5YJ3E1EA5KF328931");
vehicle1.setColor("black");
vehicle1.setDisplayName("Black Car");
vehicle1.setId(1L);
}
@Test
@WithMockUser("USER")
public void findVehicleByIdSuccess() throws Exception {
//Given **I think the problem is here***
when(vService.findVehicleById(any(),any(),any())).thenReturn(vehicle1);
//When
this.mockMvc.perform(get("/vehicles/1")).andDo(print())
//Then
.andExpect(status().isOk());
}
}
Вот соответствующий метод контроллера:
@Secured("ROLE_USER")
public class VehicleController {
@JsonView(VehicleView.summary.class)
@GetMapping("/vehicles/{id}")
public Vehicle findVehicleById(@PathVariable Long id, Principal principal,
HttpServletRequest request) throws ItemNotFoundException {
log.info("In controller " +LogFormat.urlLogFormat(request,principal.getName()));
return vehicleService.findVehicleById(id,principal, request);
}
Вот MockHTTPServletResponse. Он имеет статус 200, но тело пусто
MockHttpServletResponse:
Status = 200
Error message = null
Headers = [X-Content-Type-Options:"nosniff", X-XSS-Protection:"1; mode=block", Cache-Control:"no-cache, no-store, max-age=0, must-revalidate", Pragma:"no-cache", Expires:"0", X-Frame-Options:"DENY"]
Content type = null
Body =
Forwarded URL = null
Redirected URL = null
Cookies = []
Для справки вот метод сервиса, который я пытаюсь смоделировать
@Override
public Vehicle findVehicleById(Long id, Principal principal, HttpServletRequest request) throws ItemNotFoundException {
Optional<Vehicle> vehicle = vehicleRepository.findByIdAndUserId(id,principal.getName());
if (vehicle.isPresent()){
return vehicle.get();
} else {
throw new ItemNotFoundException(id,"vehicle");
}
}
Я пробовал разные версии Springboot но это не помогло. Я начал использовать 2.2.4, но решил, что попробую поезд 2.1.Х, так как он дольше. Я могу подтвердить, что вызывается правильный метод в контроллере из-за вывода журнала, который я получаю.