简体   繁体   English

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

[英]How mock private method that modify private variables?

How mock private method that modify private variables? 如何模拟修改私有变量的私有方法?

class SomeClass{
    private int one;
    private int second;

    public SomeClass(){}

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

    private void complexInitialization(){
        one = ...
        second = ...
    }
}

You don't , because your test will depend on implementation details of the class it is testing and will therefore be brittle. 您不需要 ,因为您的测试将取决于所测试类的实现细节,因此会很脆弱。 You could refactor your code such that the class you are currently testing depends on another object for doing this calculation. 您可以重构代码,以使当前正在测试的类依赖于另一个对象来进行此计算。 Then you can mock this dependency of the class under test. 然后,您可以模拟被测类的这种依赖性。 Or you leave the implementation details to the class itself and sufficiently test it's observable behavior. 或者,您将实现细节留给类本身,并充分测试它的可观察行为。

The problem you could suffer from is that you are not exactly separating commands and queries to your class. 您可能会遇到的问题是您没有将命令和查询完全分开。 calculateSomething looks more like a query, but complexInitialization is more of a command. calculateSomething看起来更像是一个查询,但complexInitialization更多的是命令。

Provided the fact that other answers are pointing out that such test cases are brittle and that the test cases should not be based on implementation and should be dependent on the behavior if you still want to mock them then here are some ways: 如果其他答案指出这样的测试用例很脆弱,并且如果您仍然想模拟它们,那么这些测试用例就不应基于实现,而应该取决于行为,那么可以采用以下几种方法:

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);

This is how you would do it with PowerMock. 这就是使用PowerMock的方式。

expectPrivate() of PowerMock does this. PowerMock的ExpectPrivate()完成此操作。

Test cases from PowerMock which test the private method mocking PowerMock的测试用例,用于测试私有方法模拟

UPDATE: Partial Mocking with PowerMock there are some disclaimers and catches 更新: 使用PowerMock部分模拟有一些免责声明和注意事项

class CustomerService {

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

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

Then you create a PARTIAL mock of CustomerService, giving a list of methods you want to mock. 然后,创建CustomerService的PARTIAL模拟,并提供要模拟的方法列表。

CustomerService customerService = PowerMock.createPartialMock(CustomerService.class, "subscribeToNewsletter");
customerService.subscribeToNewsletter(anyObject(Customer.class));

replayAll();

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

So add() within the CustomerService mock is the REAL thing you want to test and for the method subscribeToNewsletter() you now can write an expectation as usual. 因此,CustomerService模拟中的add()是您要测试的真实对象,对于方法subscribeToNewsletter()您现在可以照常编写期望。

Power mock might help you here. 模拟电源可能会在这里为您提供帮助。 But generally I would make the method protected and override the previously-private method to do what ever I wanted it to do. 但是通常,我将使该方法受到保护,并覆盖以前的私有方法以执行我想执行的任何操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM