存根链式空洞方法

时间:2016-07-27 00:02:50

标签: java unit-testing mockito

我想知道当void方法是方法调用链中的最后一个方法时,如何对void方法的操作进行存根。例如,我们有以下(极简化)类:

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
        // ...
    }
}

当嵌套依赖项引发异常时,我们如何为该案例编写测试?

@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());
}

测试1 - 不起作用,因为getDao()不会抛出异常:

org.mockito.exceptions.base.MockitoException: 
Checked exception is invalid for this method!

测试2 - 因此失败:

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

测试3 - 工作,但不像其他人那样可读;没有利用RETURN_DEEP_STUBS。

是否存在利用RETURN_DEEP_STUBS的不同存根方式?

0 个答案:

没有答案