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

标签 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",相反它仍在执行其真正的功能。

我在这里错过了什么?

最佳答案

An instance of AnotherClass is created inside myFunction then the instance is used to call secondClass.anotherFunction from inside myFunction.

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

public class MyClass {

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

        int result = secondClass.anotherFunction(someValue);

        //...

        return result;
    }    
}

How can I use the mocked instance instead?

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

关于java - 从另一个类方法内部调用时无法正确模拟方法调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52650052/

相关文章:

arrays - 单元测试不工作 - Ruby 使用测试单元

java - 测试抽象类中的方法一次,而不是每次实现

java - @InjectMocks @Autowired 在一起问题

java - 从命令行运行包中的java

java - 为可测试性设计构造函数

java - struts 中的请求属性行为

python - 如何在 PyDev 中运行单独的 Django 测试

java - 更改单元测试的私有(private)方法行为

java - 从 cxf 消息中获取 Http 请求正文

java - 链表的大小