Getting NotAMockException on the below Test Case

You are mixing things up here. There is an important difference between @Mock and @MockBean.

You use the first annotation if you want to write a unit test without any Spring Context support (speak @SpringBootTest, @DataJpaTest, etc.). For such tests, you can use @Mock and @InjectMocks.

As you are writing an integration test (you are starting the whole context with @SpringBootTest), you work with managed Spring beans inside your test. Hence you are not writing a unit test anymore.

If you want to replace a Spring bean with a mocked version of it inside your Spring Test Context, you have to use @MockBean:

@SpringBootTest(classes = TestApp.class)
@RunWith(SpringRunner.class)
@RunWith(MockitoJUnitRunner.class) // will do the Captor initialization for you
public class TestClass {  

  @Captor 
  private ArgumentCaptor<Object> captor;

  @MockBean 
  private FetchFileDetailsDAO dao;

  @Autowired 
  private FileEventListener listener;


  @Test
  @Transactional
  @Rollback(true)
  public void test() throws Exception {
    FileEvent ev = new FileEvent();
    // ...
    listener.onApplicationEvent(ev);
    verify(dao, times(1)).getDetailsForFile((String)captor.capture())
  }

Starting the whole context however for this test is IMHO overkill. You are better off writing a good old unit test with just JUnit and Mockito.

In addition to this, also I would rethink what benefit your current tests adds to your project as it is literally duplicating the business logic. Maybe there is more code that is not present here.

You can find a more detailed summary for the difference between @Mock and @MockBean in this article.

CLICK HERE to find out more related problems solutions.

Leave a Comment

Your email address will not be published.

Scroll to Top