Pikachu
Pikachu

Reputation: 339

Why bean is not initialized when used @MockBean annotation in unit test

I have a very bad bean implementation

@Component
public class Repository{
    public List<String> people= new ArrayList<>();

And I also have a test where I replace the repository with a mock. But when I try to access the "people" field in the test via the repository mock i get NullPointerException

@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class MainControllerTest{

    @Autowired
    private MockMvc mockMvc;
        
    @MockBean
    private Repository repository;
           
    @Test
    public void someTest(){
        repository.people // null -> NullPointerException
    }
}

Why it happens? Is the bean initialized initially or not? What's the correct solution with such a bad implementation?

Upvotes: 0

Views: 2722

Answers (1)

maveriq
maveriq

Reputation: 516

Bean initialized as it suppose to be with @MockBean. It produces just a stub for you. All nested stuff of the Repository class is ignored. In your case you have a completely initialized mock. But of course it's nested fields are null. Becase it is a mock and nested fields will not be initialized. Mock assumes that you just need kind of wrapper of that particular class to mock some behavior on that.

What you need to do is to change @MockBean to the @SpyBean. In that case your class fields would be initialized as it defined in your Repository class. So, you will have a real Repository object but wrapped with Mockito Spy. And it will allow you to perform all testing manipulations on that object that needed.

Upvotes: 3

Related Questions