集成测试和 spring 应用程序事件
Integration testing and spring application events
我有一个 spring 触发 ApplicationEvent 的休息控制器
@RestController
public class VehicleController {
@Autowired
private VehicleService service;
@Autowired
private ApplicationEventPublisher eventPublisher;
@RequestMapping(value = "/public/rest/vehicle/add", method = RequestMethod.POST)
public void addVehicle(@RequestBody @Valid Vehicle vehicle){
service.add(vehicle);
eventPublisher.publishEvent(new VehicleAddedEvent(vehicle));
}
}
我对控制器进行了集成测试,比如
@RunWith(SpringRunner.class)
@WebMvcTest(controllers = VehicleController.class,includeFilters = @ComponentScan.Filter(classes = EnableWebSecurity.class))
@Import(WebSecurityConfig.class)
public class VehicleControllerTest {
@Autowired
private MockMvc mockMvc;
@MockBean
private VehicleService vehicleService;
@Test
public void addVehicle() throws Exception {
Vehicle vehicle=new Vehicle();
vehicle.setMake("ABC");
ObjectMapper mapper=new ObjectMapper();
String s = mapper.writeValueAsString(vehicle);
given(vehicleService.add(vehicle)).willReturn(1);
mockMvc.perform(post("/public/rest/vehicle/add").contentType(
MediaType.APPLICATION_JSON).content(s))
.andExpect(status().isOk());
}
}
现在,如果我删除事件发布行,测试就会成功。但是,对于该事件,它会遇到错误。
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.IllegalArgumentException: null source
我尝试了很多不同的方法来避免或跳过测试线,但没有任何帮助。您能告诉我测试此类代码的正确方法是什么吗?提前致谢
我在本地重现了这个问题,这个异常...
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.IllegalArgumentException: null source
... 强烈地 意味着你的 VehicleAddedEvent
的构造函数看起来像这样:
public VehicleAddedEvent(Vehicle vehicle) {
super(null);
}
如果您进一步查看堆栈跟踪,您可能会看到类似这样的内容:
Caused by: java.lang.IllegalArgumentException: null source
at java.util.EventObject.<init>(EventObject.java:56)
at org.springframework.context.ApplicationEvent.<init>(ApplicationEvent.java:42)
所以,回答你的问题;问题不在于您的测试,而在于 VehicleAddedEvent
构造函数中的 super 调用,如果您更新调用 super(vehicle)
而不是 super(null)
那么事件发布将不会抛出一个例外。
这将允许您的测试完成,尽管您的测试中没有任何内容断言或验证此事件已发布,因此您可能需要考虑为此添加一些内容。您可能已经实现了 ApplicationListener<Vehicle>
(如果没有,那么我不确定发布 'vehicle event' 的好处是什么),因此您可以 @Autowire
将其 VehicleControllerTest
和验证车辆事件是否像这样发布:
// provide some public accessor which allows a caller to ask your custom
// application listener whether it has received a specific event
Assert.assertTrue(applicationListener.received(vehicle));
我有一个 spring 触发 ApplicationEvent 的休息控制器
@RestController
public class VehicleController {
@Autowired
private VehicleService service;
@Autowired
private ApplicationEventPublisher eventPublisher;
@RequestMapping(value = "/public/rest/vehicle/add", method = RequestMethod.POST)
public void addVehicle(@RequestBody @Valid Vehicle vehicle){
service.add(vehicle);
eventPublisher.publishEvent(new VehicleAddedEvent(vehicle));
}
}
我对控制器进行了集成测试,比如
@RunWith(SpringRunner.class)
@WebMvcTest(controllers = VehicleController.class,includeFilters = @ComponentScan.Filter(classes = EnableWebSecurity.class))
@Import(WebSecurityConfig.class)
public class VehicleControllerTest {
@Autowired
private MockMvc mockMvc;
@MockBean
private VehicleService vehicleService;
@Test
public void addVehicle() throws Exception {
Vehicle vehicle=new Vehicle();
vehicle.setMake("ABC");
ObjectMapper mapper=new ObjectMapper();
String s = mapper.writeValueAsString(vehicle);
given(vehicleService.add(vehicle)).willReturn(1);
mockMvc.perform(post("/public/rest/vehicle/add").contentType(
MediaType.APPLICATION_JSON).content(s))
.andExpect(status().isOk());
}
}
现在,如果我删除事件发布行,测试就会成功。但是,对于该事件,它会遇到错误。
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.IllegalArgumentException: null source
我尝试了很多不同的方法来避免或跳过测试线,但没有任何帮助。您能告诉我测试此类代码的正确方法是什么吗?提前致谢
我在本地重现了这个问题,这个异常...
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.IllegalArgumentException: null source
... 强烈地 意味着你的 VehicleAddedEvent
的构造函数看起来像这样:
public VehicleAddedEvent(Vehicle vehicle) {
super(null);
}
如果您进一步查看堆栈跟踪,您可能会看到类似这样的内容:
Caused by: java.lang.IllegalArgumentException: null source
at java.util.EventObject.<init>(EventObject.java:56)
at org.springframework.context.ApplicationEvent.<init>(ApplicationEvent.java:42)
所以,回答你的问题;问题不在于您的测试,而在于 VehicleAddedEvent
构造函数中的 super 调用,如果您更新调用 super(vehicle)
而不是 super(null)
那么事件发布将不会抛出一个例外。
这将允许您的测试完成,尽管您的测试中没有任何内容断言或验证此事件已发布,因此您可能需要考虑为此添加一些内容。您可能已经实现了 ApplicationListener<Vehicle>
(如果没有,那么我不确定发布 'vehicle event' 的好处是什么),因此您可以 @Autowire
将其 VehicleControllerTest
和验证车辆事件是否像这样发布:
// provide some public accessor which allows a caller to ask your custom
// application listener whether it has received a specific event
Assert.assertTrue(applicationListener.received(vehicle));