如何在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。但我也想要测试使用识别产品方法的getDTO方法。

你不需要模拟你的recognizeProduct方法。只要模拟DAOfacade,行为是已知的和确定的,因此可以验证getDTOrecognizeProduct的结果。

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

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

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

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

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

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

有时无法避免测试内部实现,因为某些方法不返回任何内容,并且您需要"断言"某些内容。在这种情况下,您似乎在某个时候返回了一些东西,我会专注于测试它。

在我看来,你对测试这个词有一个(可悲的常见)误解; 它并不意味着"从测试用例执行"。

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

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

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

相关内容

  • 没有找到相关文章

最新更新