从另一个类方法内部调用时无法正确模拟方法调用

Art*_*nis 1 java unit-testing mockito powermockito

MyClass firstClass = PowerMockito.spy(new MyClass());

AnotherClass secondClass;
secondClass = PowerMockito.mock(AnotherClass.class);
PowerMockito.when(secondClass.anotherFunction(Mockito.any()).thenReturn(1);

int myInt = firstClass.myFunction();

if (myInt == 1) {
    System.out.println("true");
}
Run Code Online (Sandbox Code Playgroud)

myFunction调用anotherFunction并返回 的结果anotherFunction

但它并没有像我期望的那样返回1并打印"true“,而是仍在执行其真正的功能。

我在这里缺少什么?

Nko*_*osi 5

在 myFunction 内部创建 AnotherClass 的实例,然后该实例用于从 myFunction 内部调用 secondaryClass.anotherFunction。

正确的。这意味着使用真实实例,而不是模拟实例。被测试的方法与依赖项紧密耦合,因为它自己创建一个真实的实例

public class MyClass {

    public int myFunction() {
        AnotherClass secondClass = new AnotherClass();

        int result = secondClass.anotherFunction(someValue);

        //...

        return result;
    }    
}
Run Code Online (Sandbox Code Playgroud)

我怎样才能使用模拟实例呢?

您可以重构以通过构造函数或方法参数注入第二个类,这是一个干净的代码设计,或者使用 powermock 来模拟第二个类的初始化,在我看来这是糟糕的设计。

@RunWith(PowerMockRunner.class)
@PrepareForTest(MyClass.class) //<-- you must prepare the class creating the new instance
public class MyClassTest {
    @Test
    public void test() {
        //Arrange
        int expected = 1;                          
        //Mock second class
        AnotherClass secondClass;
        secondClass = PowerMockito.mock(AnotherClass.class);
        PowerMockito.when(secondClass.anotherFunction(Mockito.any()).thenReturn(expected);

        //mocking initialization of second class withing first class
        PowerMockito.whenNew(AnotherClass.class).withNoArguments().thenReturn(secondClass);

        MyClass firstClass = new MyClass();

        //Act
        int actual = firstClass.myFunction();

        //Assert                
        assertEquals(expected, actual);
    }
}
Run Code Online (Sandbox Code Playgroud)

参考如何模拟新对象的构造