I'm wondering how to stub a void method's actions when the void method is a the last method in a chain of method invocations. For example, we have the following (extremely simplified) classes:
public class MyClass {
@Resource
private MyDependency myDependency;
public void put(Item item) {
myDependency.getDao().putItem(item);
}
}
public class MyDependency {
@Getter
private MyDao myDao;
}
public class MyDao {
public void putItem(Item item) throws Exception {
// saves item to database
// ...
}
}
How do we write a test for the case when a nested dependency throws an exception?
@InjectMocks
private MyClass myClass;
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private MyDependency injectedMyDependency;
private void stubDependencyException1() throws Exception {
doThrow(new Exception())
.when(injectedMyDependency).getDao().putItem(any());
}
private void stubDependencyException2() throws Exception {
doThrow(new Exception())
.when(injectedMyDependency.getDao()).putItem(any());
}
private void stubDependencyException3() throws Exception {
MyDao mockDao = mock(MyDao.class);
when(injectedMyDependency.getDao()).thenReturn(mockDao);
doThrow(new Exception()).when(mockDao).putItem(any());
}
@Test
public void test1() throws Exception {
stubDependencyException1();
myClass.put(new Item());
}
@Test
public void test2() throws Exception {
stubDependencyException2();
myClass.put(new Item());
}
@Test(expected = Exception.class)
public void test3() throws Exception {
stubDependencyException3();
myClass.put(new Item());
}
Test 1 - does not work because the getDao() does not throw an exception:
org.mockito.exceptions.base.MockitoException:
Checked exception is invalid for this method!
Test 2 - fails for this reason:
org.mockito.exceptions.misusing.UnfinishedStubbingException:
Unfinished stubbing detected here:
-> at com.blah...
E.g. thenReturn() may be missing.
Examples of correct stubbing:
when(mock.isOk()).thenReturn(true);
when(mock.isOk()).thenThrow(exception);
doThrow(exception).when(mock).someVoidMethod();
Hints:
1. missing thenReturn()
2. you are trying to stub a final method, you naughty developer!
3: you are stubbing the behaviour of another mock inside before 'thenReturn' instruction if completed
Test 3 - works, but not as readable as others; does not take advantage of RETURN_DEEP_STUBS.
Is there a different way of stubbing that takes advantage of RETURN_DEEP_STUBS?
Aucun commentaire:
Enregistrer un commentaire