Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 模拟内部最终对象_Java_Unit Testing_Mocking_Mockito - Fatal编程技术网

Java 模拟内部最终对象

Java 模拟内部最终对象,java,unit-testing,mocking,mockito,Java,Unit Testing,Mocking,Mockito,我正在尝试为预先存在的类编写一个测试 class ClassToBeTested { private final Obj1 a; ClassToBeTested(String anotherVariable) { a = new Obj1(anotherVariable); } public void methodToBeTested() { if(invokeSomeOtherMethod()) { a.getAnotherVar

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

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;
 }

}
下面是我的测试课:

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

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

另外,由于verify()需要模拟版本的obj1,因此它会向我抛出一个错误:
需要但未调用:x.getObj1(),但是与此模拟存在其他交互:x.invokeSomeOtherMethod()


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

您似乎不知道如何正确地进行依赖项注入。为了使测试更容易,您不需要更改所有代码-只需使用构造函数伸缩,例如:

class ClassToBeTested {

  private final Obj1 a;

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

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


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

修改构造函数以便注入
a
?我希望避免这种情况,因为它需要在项目中的多个文件之间进行更改。另外,a的初始化并不直接依赖于调用它的代码,因为另一个变量只是当前未使用的字符串。我不理解您的代码。你的类只显示一个构造函数——没有没有没有参数的构造函数。但是您使用的构造函数在测试方法中没有参数。哪一个是对的?对不起…我的错。。。纠正它。。。有一个带有一个字符串参数的构造函数。您的问题是在
spyX
对象上调用
verify
,而在
Obj1
对象上尝试验证方法调用。可能最简单的方法是添加第二个构造函数,在这里传入一个
Obj1
,而不是
字符串
。然后在测试中使用第二个构造函数,并传入一个mock
Obj1
,然后进行验证。