Springboot @MockBean not being injected when running other tests with whole context

3.3k Views Asked by At

I'm facing some problems when trying to inject a bean with the annotation @MockBean inside a Junit test. As a result I get the real service injected instead of the mocked one, but the weird behavior is that this only happens when running tests with maven verify (together with other integration tests).

Basically, the bean I want to mock is injected inside a Listener (@Component) that is triggered by a message sent on the queue during the integration test. When the listener runs, the service inside it is the real one instead of the mocked one.

It seems to me that, when running other tests, the real bean is previously injected inside the context and @MockBean, although it should restart the spring context, does not replace the existing bean with the mocked one when it encounters a bean of the same type.

This is really a strange behavior, because documentation says "Any existing single bean of the same type defined in the context will be replaced by the mock". Well, this is not happening.

Below you find snippets showing how this is done.

Service to be mocked is:

@Slf4j
@Service
@Transactional
public class SomeServiceImpl implements SomeService {
   
   @Override
   @Async
   public void doStuff(){
      ...
   }
}

A listener that injects my service like this

@Slf4j
@Component
@Transactional
public class SagaListener {
    
    @Autowired
    private SomeService someService;
    
    @JmsListener(destination = "${mydestinationtopic}", containerFactory = "myFactory",
    subscription = "my-subscription", selector = "eventType = 
    'MY_EVENT'" )
    public void receive(MyEventClass event) {
        someService.doStuff();
    }
}

And here is my test class

@Slf4j
@SpringBootTest
@RunWith(SpringRunner.class)
public class SagaListenerIT {

    @MockBean
    private SomeService someService;
    
    @Autowired
    private Sender sender;

    @Test
    public void createNamespaceSuccess() throws InterruptedException {
        ...
        sender.send(event, event.getEventType(), myTopic);
        BDDMockito.then(someService).should().doStuff();
    }

}

As a result I get that mockito says that someService made 0 invokations, and this is because the real service is being called.

Why isn't @MockBean replacing the real bean? Should't the context be reinitialized?

I've tried to add @DirtiesContext annotation in other tests and in that case everything works, but this is not a clean solution.

here is a portion of my pom where failsafe plugin is defined. It's a really simple one by the way:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-failsafe-plugin</artifactId>
    <executions>
        <execution>
            <goals>
                <goal>integration-test</goal>
            </goals>
        </execution>
    </executions>
</plugin>

Thank you

0

There are 0 best solutions below