如何模拟修改私有变量的私有方法?

4
如何模拟修改私有变量的私有方法?
class SomeClass{
    private int one;
    private int second;

    public SomeClass(){}

    public int calculateSomething(){
        complexInitialization();
        return this.one + this.second;
    }

    private void complexInitialization(){
        one = ...
        second = ...
    }
}
3个回答

8
您不需要这样做,因为您的测试将依赖于被测试类的实现细节,从而变得脆弱。您可以重构代码,使当前正在测试的类依赖于另一个对象来进行计算。然后,您可以模拟正在测试的类的此依赖关系。或者,您可以将实现细节留给类本身,并充分测试其可观察行为。
您可能会遇到的问题是,您没有完全将命令和查询分离到您的类中。`calculateSomething`看起来更像一个查询,但`complexInitialization`更像是一个命令。

第一段的最后一句话是正确答案。测试需要基于“行为”,而不是基于实现。请查看各种答案(包括我的)在 http://stackoverflow.com/questions/18435092/how-to-unit-test-a-private-variable/18435828#18435828 上非常相似的问题。 - Dawood ibn Kareem

2
鉴于其他答案指出这些测试用例是脆弱的,测试用例不应基于实现而应依赖于行为,如果你仍想模拟它们,以下是一些方法:
PrivateMethodDemo tested = createPartialMock(PrivateMethodDemo.class,
                                "sayIt", String.class);
String expected = "Hello altered World";
expectPrivate(tested, "sayIt", "name").andReturn(expected);
replay(tested);
String actual = tested.say("name");
verify(tested);
assertEquals("Expected and actual did not match", expected, actual);

这是使用PowerMock的方法。
PowerMock的expectPrivate()可以实现这一点。 来自PowerMock的测试用例测试私有方法模拟 更新:使用PowerMock进行部分模拟时有一些免责声明和注意事项。
class CustomerService {

    public void add(Customer customer) {
        if (someCondition) {
            subscribeToNewsletter(customer);
        }
    }

    void subscribeToNewsletter(Customer customer) {
        // ...subscribing stuff
    }
}

然后你创建一个部分模拟的CustomerService,列出你想要模拟的方法列表。
CustomerService customerService = PowerMock.createPartialMock(CustomerService.class, "subscribeToNewsletter");
customerService.subscribeToNewsletter(anyObject(Customer.class));

replayAll();

customerService.add(createMock(Customer.class));

所以,在CustomerService模拟中的add()是你想要测试的真正内容,对于subscribeToNewsletter()方法,你现在可以像往常一样编写期望。

你模拟私有方法,它会返回结果,而不是修改内部字段。 - Cherry

1

PowerMock可能会对您有所帮助。但通常情况下,我会将该方法设置为protected,并覆盖先前的私有方法以执行我想要的任何操作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接