Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mocking exceptions with Mockito: Unexpected Exception error

This is the code of my service:

public class Service {
   public Object serviceMethod() throws MyException {
      @Autowired
      Dao dao;

      try {
         return dao.dao_method();
      } catch (ExceptionFromDaoMethod e) {
         throw (new MyException());
      }
   }
}

I want to write a simple Unit Test; this is my test case:

@Mock
Dao dao;

@InjectMocks
Service service;

@Test(expected=MyException.class)
public void shouldReturnMyException throws MyException {
   when(service.serviceMethod()).thenThrow(new MyException());
}

This test fails, because I have an Unexpected exception:

the expected exception is MyException but was org.mockito.exception.base.MockitoException

Why? What is the solution?

Update Thanks to @Maciej Kowalski I have noted that I was using the when condition versus a real class and not versus a mocked one. So I added the annotation @Spy to the Service in the Unit Test.
The code of the new test is:

@Mock
Dao dao;

@InjectMocks
@Spy
Service service;

@Before
MockitoAnnotations.initMocks(this);

@Test(expected=MyException.class)
public void shouldReturnMyException throws MyException {
   doThrow(new MyException()).when(service.serviceMethod());
}

But now I have this problem:

the expected exception is MyException but was

like image 670
PenguinEngineer Avatar asked Dec 10 '25 05:12

PenguinEngineer


1 Answers

You would have to @spy the Service as i assume you are using it as the instance with real implementation being invoked.

So try this:

@InjectMocks
@Spy
Service service;

@Test(expected=MyException.class)
public void shouldReturnMyException throws MyException {
   doThrow(new MyException()).when(service).serviceMethod();
}

remember to start with doXX when mocking a @Spy.

Update

If you want to mock the dao call (which is a better test candidate..) you would have to make some changes if you only want to use plain Mockito.

If the dao is not your instance dependency then you will have to change your prod method:

public class Service {
   public Object serviceMethod() throws MyException {
      Dao dao = getDaoInstance();
      try {
         return dao.dao_method();
      } catch (ExceptionFromDaoMethod e) {
         throw (new MyException());
      }
   }

   Dao getDaoInstance(){
      return new Dao();
   }
}

And your test class should me more or less like this:

@Mock
Dao dao;

@Spy
Service service;

@Test(expected=MyException.class)
public void shouldReturnMyException throws MyException {
   doReturn(dao).when(service).getDaoInstance();

   when(dao.dao_method()).thenThrow(new ExceptionFromDaoMethod());

   service.serviceMethod();
}
like image 86
Maciej Kowalski Avatar answered Dec 12 '25 17:12

Maciej Kowalski