I have a spring rest controller which fires a 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));
}
}
And I have a integration test for the controller, something like
@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());
}
}
Now, if I remove the event publishing line, the test successes. However, with the event, it hits error.
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.IllegalArgumentException: null source
I tried bunch of different things, to avoid or skip the line in testing but nothing helped. Could you please tell me what is the right way to test such code? Thanks in advance
I have reproduced this issue locally and this exception ...
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.IllegalArgumentException: null source
... strongly implies that the constructor of your VehicleAddedEvent
looks like this:
public VehicleAddedEvent(Vehicle vehicle) {
super(null);
}
If you look further down the stacktrace you'll likely see something like this:
Caused by: java.lang.IllegalArgumentException: null source
at java.util.EventObject.<init>(EventObject.java:56)
at org.springframework.context.ApplicationEvent.<init>(ApplicationEvent.java:42)
So, in answer to your question; the issue is not with your test, it is with the super call in the VehicleAddedEvent
constructor and if you update that such that is calls super(vehicle)
rather than super(null)
then the event publication will not throw an exception.
This will allow your test to complete although there is nothing in your test which asserts on or verifies that this event has been published so you may want to look into adding something for that. You probably already have an implementation of ApplicationListener<Vehicle>
(if not then I'm not sure what the benefit of publishing the 'vehicle event' is) so you could @Autowire
that into VehicleControllerTest
and verify that the vehicle event was published like this perhaps:
// 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));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With