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

时间:2018-10-04 15:08:52

标签: 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");
}

myFunction调用anotherFunction并返回anotherFunction的结果。

但是它并没有像我期望的那样返回1并打印"true“,相反,它仍然在执行其实际功能。

我在这里想念什么?

1 个答案:

答案 0 :(得分:3)

  

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

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

public class MyClass {

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

        int result = secondClass.anotherFunction(someValue);

        //...

        return result;
    }    
}
  

我该如何使用模拟的实例?

您可以通过构造函数或方法参数重构注入第二个类,这是干净的代码设计,或者您使用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);
    }
}

引用How to mock construction of new objects