我已经编写了一个典型的三层Spring Boot REST API,并正在为此进行测试。 API本身运行良好,但是我遇到了使控制器测试正常工作的问题。返回的主体为空,因为控制器层返回的对象为null。这是游戏中的主要依赖项。
<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.X火车,因为它已经存在了很长时间。由于我得到的日志输出,我可以确认正在调用控制器中的正确方法。
您确实模拟了服务对象,但没有将其注入到控制器中。
@InjectMocks
private VehicleController vehicleController = new VehicleController();
使用MockitoAnnotations.initMocks(this)
初始化这些模拟对象,而不是自动装配MockMvc
对象,而是像这样通过控制器来传递它:
@BeforeEach
void setup() {
MockitoAnnotations.initMocks(this);
this.mockMvc = MockMvcBuilders.standaloneSetup(vehicleController).build();