模拟内部最终对象

时间:2017-04-18 23:01:57

标签: java unit-testing mocking mockito

我正在尝试为预先存在的类编写测试。

def func(foo):
    return foo

def anotherfunc(foo, bar, k=None):
    if k == None:
        k = func(foo)
    #process whatever

以下是我的测试类:

class ClassToBeTested {

  private final Obj1 a;

  ClassToBeTested(String anotherVariable) {

     a = new Obj1(anotherVariable);
  }

 public void methodToBeTested() {

     if(invokeSomeOtherMethod()) {
          a.getAnotherVariable().doSomething();
     } 
 }

 public boolean invokeSomeOtherMethod() { 
         // return true or false based on some logic
 }

 Obj1 getObj1() {
     return a;
 }

}

这是我的理解: 由于obj1是在类构造函数中创建的私有final对象,因此它既不能在测试方法中直接访问,也不会强制spyObject使用模拟版本的obj1。

此外,由于verify()需要模拟版本的obj1,它会抛出一个错误: class TestClass { @Test public void testMethod() { ClassToBeTested x = new ClassToBeTested("someString"); ClassToBeTested spyX = spy(x); doReturn(false).when(spyX).invokeSomeOtherMethod(); spyX.methodToBeTested(); verify(spyX, times(1)).getObj1().doSomething(); } }

我的理解错了吗?测试testMoethod()的方法是什么?

1 个答案:

答案 0 :(得分:1)

您似乎不明白如何正确执行依赖注入。您不需要更改所有代码以便更容易测试 - 只需使用构造函数telescoping,例如:

class ClassToBeTested {

  private final Obj1 a;

  public ClassToBeTested(String anotherVariable) {
   this(new Obj1(anotherVariable));
  }

  ClassToBeTested(Obj1 a) {
    this.a = a;
  }

完成。现在您有了一个受包受保护的构造函数,您可以使用它直接插入 a 的实例。所有其他生产代码都可以保持原样。

换句话说:不要使用模拟框架技巧“修复”您的设计问题。