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_Mockito_Stubbing - Fatal编程技术网

Java 模拟来自另一个类的方法调用

Java 模拟来自另一个类的方法调用,java,unit-testing,mockito,stubbing,Java,Unit Testing,Mockito,Stubbing,我的代码结构: class A { void methodA() { //some code B b = new B(); response = b.methodB(arg1, arg2); //some code using "response" } } 我正在单元测试类A,不想实际调用methodB()。有没有办法通过自定义响应模拟此方法调用。 我尝试按如下方式模拟此方法调用: B classBMock = M

我的代码结构:

class A {
    void methodA() {
        //some code
        B b = new B();
        response = b.methodB(arg1, arg2);
        //some code using "response"
    }
}
我正在单元测试类A,不想实际调用methodB()。有没有办法通过自定义响应模拟此方法调用。 我尝试按如下方式模拟此方法调用:

B classBMock = Mockito.mock(B.class);
Mockito.when(classBMock.methodB(arg1, arg2)).thenReturn(customResponse);
A objA = new A();
objA.methodA();
在以上述方式调用methodA()时,当在A中调用methodB()时,我不会得到customResponse。但当我使用classBMock调用methodB()时,我会得到customResponse。
调用methodA()时,我是否可以从methodB()获取customResponse。

一种常见的方法是将collaborator实例的创建提取到一个方法中,然后对要测试的类执行间谍操作

在这种情况下,您可以像这样重写
A

public class A {
    public B createB() {
        return new B();
    }

    public void methodA() {
        //some code
        B b = createB();
        response = b.methodB(arg1, arg2);
       //some code using "response"
    }
}
现在,您的测试可以
spy
您正在测试的
A
实例,并为
B
注入模拟:

B classBMock = Mockito.mock(B.class);
Mockito.when(classBMock.methodB(arg1, arg2)).thenReturn(customResponse);
A objA = Mockito.spy(new A());
Mockito.when(objA.createB()).thenReturn(classBMock());
objA.methodA();

编辑:
如果您无法修改
A
,另一种方法是使用。请注意,此代码段仅显示相关的模拟,不显示允许PowerMock插入类所需的注释:

B classBMock = Mockito.mock(B.class);
Mockito.when(classBMock.methodB(arg1, arg2)).thenReturn(customResponse);
PowerMockito.whenNew(B.class).withNoArguments().thenReturn(classBMock);
A objA = new A();
objA.methodA();

谢谢你@Mureinik。这是一个可能的解决方案,但由于我无法更改原始源代码,有没有不修改代码的方法?@user2393393一个选项是PowerMock,尽管就个人而言,我不是一个粉丝。有关详细信息,请参阅我编辑的答案。谢谢@Mureinik。这就是目的。你有什么理由不喜欢PowerMock吗?只是问我是否应该知道一些事情。@user2393393 PowerMock使用字节码插装,这通常会对测试的性能产生相当大的影响,如果您的代码不是直接的,并且涉及反射,或者其他有用的字节码操作技术,则可能是不可靠的。非常感谢。