How to use @MockBean Annotation

In this tutorial, you will learn how to use @MockBean annotation in your Unit tests.

@MockBean annotation is used to create and place mocks into Spring Application Contexts. If Spring Application Context does already have a bean of the same type then this bean will be replaced with a mock object. Otherwise, a new bean(mock) will be created and added to Spring Application Context.

@MockBean as a Class-Level Annotation

@MockBean annotation can be used as a class-level annotation or as a field-level annotation. To use it as a class-level annotation:

  1. Place the @MockBean annotation right above the class name.
  2. Then inject the created mock object, using the @Autowired annotation as shown in the code example below.
@WebMvcTest(controllers = UsersController.class)
@MockBean({UsersService.class})
public class UsersControllerWebLayerTest {

    @Autowired
    private MockMvc mockMvc;

    @Autowired 
    private UsersService usersService;
    ...

}

Use @MockBeans for Multiple Mocks

It is possible that you will need to mock more than one bean. In this case, you will need to use the @MockBean annotation together with a @MockBeans annotation.

@WebMvcTest(controllers = UsersController.class)
@MockBeans({ @MockBean(UsersService.class), @MockBean(UsersRepository.class) })
public class UsersControllerWebLayerTest {

    @Autowired
    private MockMvc mockMvc;

    @Autowired 
    private UsersService usersService;

    @Autowired 
    private UsersRepository usersRepository;
    ...

}

@MockBean as a Field-Level Annotation

Instead of placing @MockBean annotation above the class name, you can place it above the member variable. In this case:

  1. Spring Framework will create a new mock object and will add it to the Spring Application Context,
  2. Then, Spring Framework will automatically inject this mock object and will assign it to a member variable.
@WebMvcTest(controllers = UsersController.class)
public class UsersControllerWebLayerTest {

    @Autowired
    private MockMvc mockMvc;

    @MockBean
    UsersService usersService;

    ...

}

If needed, use with @Qualifier Annotation

When you use @MockBean annotation, Spring Framework will create a mock object of the requested type and place it into the application context. Now, it is possible that your application will have more than one bean of the same type in the Spring Application Context. In this case, use @Qualifier annotation to specify the bean you would like to mock and work with.

@WebMvcTest(controllers = UsersController.class)
public class UsersControllerWebLayerTest {

    @Autowired
    private MockMvc mockMvc;

    @MockBean
    @Qualifier("usersService")
    UsersService usersService;

    ...

}

How is @MockBean different from @Autowired?

@MockBean and @Autowired are two annotations used in the Spring Framework, but they have different purposes.

@Autowired is used to inject an existing bean into a class that depends on it. The bean instance that is injected is the actual instance of the bean managed by the Spring container.

On the other hand, @MockBean is used to create a mock object of a Spring bean, which can be used to replace the actual bean during testing. This is useful when you want to test a component that depends on other beans, but you don’t want to use the real implementation of those beans during testing.

In summary, @Autowired injects the real instance of a bean into a component, while @MockBean creates a mock instance of a bean for testing purposes.

Can @MockBean be used with non-Spring beans?

No, @MockBean is specifically designed for mocking Spring beans. It is not intended for use with non-Spring beans.

If you want to mock a non-Spring bean in your tests, you can use a mocking framework such as Mockito or EasyMock to create a mock object. These frameworks allow you to create mock objects for any Java class or interface, regardless of whether it is managed by Spring or not. Once you have created a mock object, you can use it in your tests to simulate the behavior of the real object.

Can we use @MockBean in an integration test?

Yes, you can use @MockBean in an integration test.

@MockBean can be used to replace a real bean with a mock bean during the test execution. This can be useful when you want to isolate a component and test it in the context of the application.

In an integration test, you can use @MockBean to mock a bean that the component under test depends on. This allows you to test the component’s behavior in a controlled environment, without the need for a real implementation of the dependent bean.

It is worth noting that in an integration test, the Spring context is loaded, and the application’s beans are created and wired together. This means that you can use @Autowired to inject the dependencies of the component you are testing, as well as @MockBean to replace any beans that you want to mock during the test.

Video lessons

I hope this tutorial was of some value to you. If you like learning by watching a series of step-by-step video lessons then have a look at my video course called “Testing Java with JUnit and Mockito“. This video course is for absolute beginners and you do not need to have any prior knowledge of testing Java applications to enrol.

Explore the world of testing with our extensive Mockito tutorials featured on the Testing Java Code page. Unlock the potential of Mockito to effortlessly mock dependencies and conduct efficient testing, helping you deliver high-quality software with confidence.

Happy learning!