Version of Spring Boot: 1.4.0.M3

I have an integration test, annotated with

@RunWith(SpringRunner::class)
@SpringBootTest
@AutoConfigureMockMvc

and where I have

    @MockBean
    private lateinit var mockApplicationEventPublisher: ApplicationEventPublisher

    @Autowired
    private lateinit var mockMvc: MockMvc

Kotlin code, equivalent to

    @MockBean
    private ApplicationEventPublisher mockApplicationEventPublisher;

    @Autowired
    private MockMvc mockMvc;

The controller under test does call publishEvent() on the event publisher, but when I verify that the calls have been made using

    verify(mockApplicationEventPublisher).publishEvent(ScoreSubmittedEvent()))

I get the following error:

Wanted but not invoked:
org.springframework.context.ApplicationEventPublisher#0 bean.publishEvent(...);
-> at com.ninja_squad.ng2propack.pack.ScoreControllerTest.should submit score(ScoreControllerTest.kt:89)
Actually, there were zero interactions with this mock.

When I debug, I notice that the publisher in the test is indeed a Mockito-generated proxy, but that the publisher injected in the controller under test is the non-mocked instance of org.springframework.web.context.support.GenericWebApplicationContext.

I guess the root caus is that the bean implementing ApplicationEventPublisher is not an actual separate bean, but is the spring application context itself.

A workaround would be to use my own event publisher bean that would simply delegate to the actual spring event publisher, but that's something I shouldn't have to do.

Comment From: philwebb

As far as I can tell this is a limitation of the Spring Framework. It appears that an ApplicationEventPublisher cannot be registered as a regular bean. Take a look at AbstractApplicationContext.prepareBeanFactory and specifically the Javadoc for beanFactory.registerResolvableDependency.

You could add a additional bean to your test application context and use @EventListener to verify the event was sent. Alternatively you might be able to spy on the ApplicationEventMulticaster.

Comment From: jnizet

OK. I'll open a bug for Spring Framework then, because I think that workarounds shouldn't be necessary to support that common use-case.

Comment From: kgemmert-r7

Is there any update on that bug report, I am hitting a similar problem.

Comment From: snicoll

@kgemmert-r7 this issue is closed, check the issue that @jnizet has created.

Comment From: renannprado

I've just had the same issue. My workaround was the following

@Bean
@Primary
GenericApplicationContext genericApplicationContext(final GenericApplicationContext gac) {
    return Mockito.spy(gac);
}

Comment From: idrisssakhi

Version of Spring Boot: 1.4.0.M3

I have an integration test, annotated with

@RunWith(SpringRunner::class) @SpringBootTest @AutoConfigureMockMvc

and where I have

``` @MockBean private lateinit var mockApplicationEventPublisher: ApplicationEventPublisher

@Autowired
private lateinit var mockMvc: MockMvc

```

Kotlin code, equivalent to

``` @MockBean private ApplicationEventPublisher mockApplicationEventPublisher;

@Autowired
private MockMvc mockMvc;

```

The controller under test does call publishEvent() on the event publisher, but when I verify that the calls have been made using

verify(mockApplicationEventPublisher).publishEvent(ScoreSubmittedEvent()))

I get the following error:

Wanted but not invoked: org.springframework.context.ApplicationEventPublisher#0 bean.publishEvent(...); -> at com.ninja_squad.ng2propack.pack.ScoreControllerTest.should submit score(ScoreControllerTest.kt:89) Actually, there were zero interactions with this mock.

When I debug, I notice that the publisher in the test is indeed a Mockito-generated proxy, but that the publisher injected in the controller under test is the non-mocked instance of org.springframework.web.context.support.GenericWebApplicationContext.

I guess the root caus is that the bean implementing ApplicationEventPublisher is not an actual separate bean, but is the spring application context itself.

A workaround would be to use my own event publisher bean that would simply delegate to the actual spring event publisher, but that's something I shouldn't have to do.

@TestConfiguration static class contextConfiguration {

@Bean
@Primary
public ApplicationEventPublisher applicationEventPublisher(ApplicationEventPublisher app) {
  return Mockito.spy(app);
}

}