简体   繁体   English

Junit测试专用方法

[英]Junit test for private method

I read this question: How do I test a class that has private methods, fields or inner classes? 我读了一个问题: 如何测试具有私有方法,字段或内部类的类? and it seems that I might have a code smell, but my code is very simple to actually refactor. 看起来我可能有代码味道,但是我的代码实际上很容易重构。 what is wrong in the design that I have created. 我创建的设计有什么问题。 I have created a delegate class for processing some actions it has three methods execute(Action); 我创建了一个委托类来处理一些动作,它具有三种方法execute(Action); PopulateActionHandlers() and executeActionhandlers(); PopulateActionHandlers()executeActionhandlers(); My class is like below: 我的课如下:

public class DelegateHandler{
    Map<Integer,ActionHandlers> handlerMaps;

    public execute(Action action){
        populateActionHandlers(action);
        executeActionHandlers();

    }//end of execute

    //This method can create and populate more than one handlers in handlerMap
    private populateActionHandlers(action){
        handlerMap = new LinkedHashMap<ActionHandlers>();
        if (action.isMultimode()){
            handlerMap.add(1,new handler(action.getabc()));
            handlerMap.add(2,new handler(action.getabc()-1));
        }else{
            handlerMap.add(1,new handler(action));
        }

    }//end of populateActionHandlers

    //This method can execute more than one handlers in handlerMap
    private executeActionHandlers(){
        for(ActionHandler actionHandler : handlerMap.values){
            actionHandler.executeAction();
        }

    }//end of executeActionHandlers
}

Now I want to test populateActionHandlers() method with JUnit, which I made private as there is no need to expose it outside this class. 现在,我想用JUnit测试populateActionHandlers()方法,因为没有必要在类之外公开它,所以将其设为私有。 If I test the execute() method then it will test both populateActionHandlers() and executeActionHandlers() methods which is testing two units at the same time, I want to test them separately. 如果我测试execute()方法,那么它将同时测试两个单元的populateActionHandlers()executeActionHandlers()方法,因此我想分别测试它们。 The design (I think) seems alright to me and doesnt allow any issues but then I would either change the access to the method (and only for the sake of testing it doesn't justify that in my opinion, right?) or to use reflection (is that a good idea, it does not feel right somehow, do people usually use reflection for junit testing?). 设计(我认为)对我来说似乎还不错,并且不允许出现任何问题,但是我要么更改对方法的访问权限(并且仅出于测试目的,但我认为这样做并不合理,对吗?)或使用反射(这是一个好主意,以某种方式感觉不对,人们通常使用反射进行junit测试吗?)。 So the only thing that cant be ruled out is code smell. 因此,唯一不能排除的是代码异味。 But may be my code sinus is not really helping me So I would like to understand if I can improve this code. 但是可能是我的代码窦并没有真正帮助我,所以我想了解我是否可以改进此代码。

The recommendation not to test private methods should not prevent one to do a weird design by leaving out private method, but should enforce to test only methods that have clear semantics. 不测试私有方法的建议不应通过遗漏私有方法来防止进行怪异的设计,而应强制仅测试具有清晰语义的方法。

Private methods are usually technical helpers. 私有方法通常是技术助手。 Their semantics can change if the underlying data structures change, they can even be optimized away if the calling public methods use another algorithm to achieve the same goals. 如果底层数据结构发生更改,它们的语义可能会更改,如果调用公共方法使用另一种算法来实现相同的目标,它们甚至可以被优化。

I would rewrite the programm in following way: 我将以以下方式重写程序:

...
public execute(Action action){
    Map<Integer,ActionHandlers> handlerMap = populateActionHandlers(action);
    executeActionHandlers(handlerMap);
}
...

Storing results of one function into a private field only to retrieve it from this field in another function is not threadsafe and harder to maintain. 将一个函数的结果存储到私有字段中,以仅从另一个函数中的该字段中检索它不是线程安全的,并且很难维护。

Yet this refactoring would break all (yet not writte) tests that did test the private method of your example, because the interface is changed. 但是,由于接口已更改,因此此重构将破坏所有确实测试了示例私有方法的测试(尚未编写)。 If you had only tested the public method, the all tests would be valid after this refactoring. 如果您仅测试了公共方法,则此重构后所有测试均有效。

I know few cases where testing private methods is ok. 我知道很少可以测试私有方法。 While testing private methods is often avoidable, I think the checking of private state is sometimes a better alternative than only checking the public state of objects. 尽管通常可以避免测试私有方法,但我认为检查私有状态有时比仅检查对象的公共状态更好。 Such checks may be not as robust (reasons as above) but the public state is often incomplete and hard to assert. 这样的检查可能不那么健壮(原因如上所述),但是公共状态往往不完整且难以主张。 In both cases I use the framework picklock which enables one to access private methods and fields in a convenient way. 在这两种情况下,我都使用框架Picklock ,使用户可以方便地访问私有方法和字段。

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

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