How mock private method that modify private variables?

…衆ロ難τιáo~ 提交于 2019-12-30 10:19:27

问题


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 = ...
    }
}

回答1:


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.




回答2:


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.

expectPrivate() of PowerMock does this.

Test cases from PowerMock which test the private method mocking

UPDATE: Partial Mocking with PowerMock there are some disclaimers and catches

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 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.




回答3:


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.



来源:https://stackoverflow.com/questions/18504604/how-mock-private-method-that-modify-private-variables

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!