如何在java中正确测试类的内部方法

时间:2015-01-14 12:15:00

标签: java unit-testing testing junit mockito

如何测试以下代码?

class1 {

    public InjectedClass injectedClass; 

    method1(){
        returnValue = injectedClass.someMethod; 
        //another logic
    }

    method2(){
        resultValue = method1();
    }

}

我的应用程序是用Java开发的。我使用JUnit和Mockito。

要测试method1(),我可以为InjectedClass创建模拟,为someMethod()创建模拟逻辑。 但是如何正确测试方法呢?我是否需要为method1()创建模拟?

更新: 让我展示一个真实的例子。

public class Application { 

@Inject 
DAOFacade facade;

//method1 
 public ReturnDTO getDTO(LiveServiceRequestParam requestParam) throws AffiliateIdentityException {
        ReturnDTO returnDTO  = new ReturnDTO();

        CoreProductRepository repo = recognizeProduct(ProdCodeTypeEnum.MPN, null, vendorBound);
        if(repo!=null){
           //logic to fill some fileds in returnDTO  
        }

        return returnDTO  ;
    }

//метод2 
 CoreProductRepository recognizeProduct(ProdCodeTypeEnum paramType, String prodCode, List<Integer> vendors) {
        CoreProductRepository coreProductRepository = null;
        switch (paramType) {
            case MPN:
                coreProductRepository = facade.findByAlternativeMPN(prodCode, vendors);
                break;
            case EAN:
                coreProductRepository = facade.findByEan(prodCode, vendors);
                break;
            case DESCRIPTION:
                coreProductRepository = facade.findByName(prodCode, vendors);
                break;
        }
        return coreProductRepository;
    }
}

因此,要测试recognProduct我模拟DAOfacade。但我也想要使用recognProduct方法测试getDTO方法。

4 个答案:

答案 0 :(得分:2)

您应该将测试工作集中在公共方法的返回值上,而不是内部实现上。

专注于内部实施会导致测试更难以保持,因为不影响返回值的基本重构可能需要更改测试。

有时候不可能避免测试内部实现,因为有些方法什么都不返回,你需要&#34;断言&#34;一些东西。在这种情况下,你似乎在某些时候返回了一些东西,我专注于测试它。

答案 1 :(得分:2)

您无需模拟recognizeProduct方法。只要DAOfacade被模拟,行为就是已知且具有确定性,因此可以验证getDTOrecognizeProduct的结果。

也可以说,你甚至不需要专门测试recognizeProduct,因为它不公开,因此,没有合同要执行。只要正在测试和验证getDTO的行为,就您的API而言,您的API正在运行。实施细节并不重要。

在某种程度上,测试recognizeProduct具有适得其反的效果,它会损害代码的可维护性和可靠性而不是帮助它,因为即使它不影响,也会使重构或重组难以实现。以任何方式外部可见的行为。

答案 2 :(得分:1)

如果方法的定义如您的示例所示,则它们是包私有的。因此,如果您在同一个包中创建一个测试(通常在测试目录中),您将能够访问这些方法并对其进行测试。

那就是说,如果你可以重构或重写类更易于测试,那么这可能是一个好主意。如果确实你必须测试内部方法的结果,而不能只测试公共方法。

答案 3 :(得分:1)

在我看来,你对 test 这个词有一个(可悲的是常见的)误解; 意味着&#39;从测试用例执行&#39;。

测试意味着提供一系列输入,并断言相应的输出是正确的。 99%的时间意味着检查返回代码或对象状态,有时您必须使用模拟来正确测试纯输出接口。

如果您为公共方法执行此操作,并且私有方法完全涵盖所需的标准,则完成工作。如果私有方法中存在未覆盖的代码,则使用它来标识和添加缺少的测试用例,或者将其删除。

如果您觉得删除无法访问的私有代码会丢失有用的内容,请将其公开,或将其移至另一个类。