MockBean and MyBatis Mapper not working together (as they did before Spring Boot 2.2.7)

Viewed 1640

I am using MyBatis Spring Boot Starter version 2.1.3. Ever since moving to Spring Boot 2.2.7 (I've also tried 2.2.8 and 2.3.1 with the same results), I've had a problem using the MockBean annotation to mock a MyBatis interface (e.g. DAO). Let's say I have an interface like this one:

@Mapper
@Repository
public interface OrderDAO {
   int insertOrder(@Param("order") Order order);
}

I'd like to execute an integration test and mock this mapper within my OrderService that contains a field of type OrderDAO.

My integration test is annotated with @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) and contains this field:

@MockBean
private OrderDAO orderDAO;

When I run a test such as this and look at what the references to the OrderDAO objects are, in my integration test I see this:

com.example.dao.OrderDAO$MockitoMock$1819884459

But inside my OrderService class the field is this:

com.sun.proxy.$Proxy179 (org.apache.ibatis.binding.MapperProxy@37d9310e)

So, calls to Mockito.verify obviously don't work because my mock has not been injected into my OrderService class. Now, very oddly, I found that adding this code makes everything work:

@TestConfiguration
static class MockConfig {
    @Bean
    public OrderDAO orderDAO() {
        return Mockito.mock(OrderDAO.class);
    }
}

Adding this nested class along with adding the ContextConfiguration annotation on the integration test class, and now the object that gets injected into the OrderService class is the MockitoMock -- the same object that is referenced by the MockBean annotated field in the test class. I didn't have to do this with Spring Boot 1.2.6 and earlier and I couldn't find any reference to a change that would have caused this (although perhaps I didn't search long enough).

So, I am wondering if I am doing something incorrectly, or, am I missing something I should be doing? It seems like this should just work like it did before, which the need for this extra nested TestConfiguration class. Appreciate any insights anyone can provide. Thanks.

1 Answers

As mentioned by ave in the comments, I had to add the name to the mock bean annotation to get it to work

@MockBean(name = "orderDAO")
private OrderDAO orderDAO;
Related