spring - 集成测试和 Spring 应用程序事件

标签 spring junit mockito integration-testing

我有一个触发 ApplicationEvent 的 Spring 休息 Controller

@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));
    }
}

我有一个 Controller 的集成测试,比如
    @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

我尝试了很多不同的东西,以避免或跳过测试中的线路,但没有任何帮助。你能告诉我测试这些代码的正确方法是什么吗?提前致谢

最佳答案

我在本地重现了这个问题,这个异常(exception)......

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> (如果不是,那么我不确定发布“车辆事件”的好处是什么)所以你可以 @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 - 集成测试和 Spring 应用程序事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45128648/

相关文章:

java - 运行测试时,模拟类永远不会给出空指针

spring - PropertyPlaceholderConfigurer 无法忽略属性文件,即使 ignoreResourceNotFound=true

java - Spring 开机测试 "No qualifying bean of type available"

java - Spring + Maven + Hadoop

junit - 如何正确实现 attributeHasFieldErrors(没有 'AssertionError: No BindingResult for attribute: abc' 错误)

java - Mockito: stub 深度有多深?

java - 使用 PagedResources/嵌入对象反序列化日期。 jackson . Spring

java - 如何在 Eclipse 中使用 JUnit

intellij-idea - IntelliJ 滚动控制台在测试执行后结束

mocking - 自定义匹配器的 Mockito 错误