Mocking Exceptions with Mockito: Unexpected Exception Error
This is my service code:
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 failed because I have an unexpected exception:
the expected exception is MyException but org.mockito.exception.base.MockitoException
Why? What's the solution?
Update
Thanks to @Maciej Kowalski, I pointed out that I am using the when clause versus the real class, not the mocking one. So I added an annotation @Spy
to the service in Unit Test.
New test code:
@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
source to share
You will need @spy Service as I am assuming you are using it as an instance with a real implementation called.
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 while mocking @Spy.
Update
If you want to mock the dao call (which is the best candidate for a test ..) you will need to make some changes if you want to use a simple Mockito.
If the dao is independent of your instance, 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 I like more or less:
@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();
}
source to share
Finally I found a solution: creating unit tests for a Spring project is more difficult than I expected (at least using only the Mockito Framework), so I found a solution using some Spring Annotations as well
So this is my new working test:
@MockBean
Dao dao;
@Autowired
Service service;
@Test(expected=MyException.class)
public void shouldReturnMyException throws MyException {
when(dao.dao_method()).thenThrow(new ExceptionFromDaoMethod());
}
source to share