繁体   English   中英

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

[英]How to properly test internal method of class in java

如何测试以下代码?

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

因此,为了测试识别产品我模拟了DAOfacade。 但是我也想测试使用identifyProduct方法的getDTO方法。

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

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

有时无法避免测试内部实现,因为某些方法什么也不返回,并且您需要“断言”某些东西。 在这种情况下,您似乎在某个时候返回了一些东西,我将集中精力进行测试。

您不需要模拟您的recognizeProduct方法。 只要DAOfacade被嘲笑,行为是已知的,确定的,所以两者的结果getDTOrecognizeProduct可以验证。

也可以说,您甚至不需要专门测试recognizeProduct ,因为它不是公开的,因此没有强制执行的合同。 只要正在测试和验证getDTO的行为,就用户而言,您的API一直在起作用。 实现的细节并不重要。

从某种意义上说,测试recognizeProduct特别是适得其反,它损害了代码的可维护性和可靠性,而不是帮助了它,因为即使不以任何方式影响外部可见的行为,这也会使实现任何重构或重组变得更加困难。

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

就是说,如果您可以重构或重写类以使其更易于测试,则可能是个好主意。 如果确实需要测试内部方法的结果,而不仅仅是测试公共方法。

在我看来,您对test一词有(非常常见的)误解; 但这并不意味着“从测试的情况下执行”。

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

如果对公共方法执行此操作,并且私有方法已完全满足要求的标准,则说明已完成工作。 如果私有方法中存在未发现的代码,请使用它来识别并添加缺少的测试用例,或者将其删除。

如果您觉得删除无法访问的私有代码,将其公开或移到另一个类中会丢失一些有用的东西。

暂无
暂无

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

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