繁体   English   中英

测试使用Mockito在内部调用私有void方法的方法

[英]Testing a method which calls private void method inside using mockito

我想测试一个内部调用void方法的方法。

下面是代码

public String process(MKSConnectionParams mksConnectionParam, IProgressMonitor progressMonitor) throws Exception {

    if (null != progressMonitor) {
        progressMonitor.beginTask("Starting the creation of report", 100);
    }
    if (null == mksConnectionParam) {
        initialize(MksLibFactory.getDefault());
    }
    else {
        initialize(mksConnectionParam, MksLibFactory.getDefault());
    }
           --------------
}

public void initialize(MKSConnectionParams mksConnectionParam, IMksLibrary mksLibDefault) throws Exception {
    paramMKSConnectionParams = mksConnectionParam;
    GlobalConstants.hostName = paramMKSConnectionParams.hostname;
    GlobalConstants.port = String.valueOf(paramMKSConnectionParams.port);
    try {
        localISi = mksLibDefault.getSi(paramMKSConnectionParams);
        localIIm = mksLibDefault.getIm(paramMKSConnectionParams);
    }
    catch (MksLibException | AuthenticationError e) {
        throw e;
    }

    ProjectInfo prjInfo = localISi.getProjectInfo(pathToPj);
    projRevCmd = prjInfo.getConfigPath().getConfigPath() + "#b=" + projectRevision;

}

我正在为process()方法编写模拟测试用例。 调用initialize(mksConnectionParam, MksLibFactory.getDefault())时测试失败。 这是因为在此过程中,我们正在调用真正的mks连接,而我正在传递虚拟用户名和密码。 我们无法模拟此initialize方法。 有什么办法吗?

较小的伪代码将有很大帮助。

早些时候,我将初始化方法设置为private 将其更改为public会有所不同吗?

有多种方法可以测试这种情况,并且不同的人会主张不同的方法,主要是基于个人喜好。

请注意,对此进行测试,将需要更改您正在测试的类的代码(我相信您忽略了提及它的名称)。 有一个例外,那就是如果您使用的是PowerMock。 我不会在这里详细介绍,但是您可以在此处找到更多有关如何将其合并到您的模拟代码中的信息

回到常规测试方法,问题在于您使用的是真正的IMksLibrary而不是模拟,这是因为您在process方法内部获得了对其的引用。 这是您可能要考虑的一些方法:

  1. 更改process方法的签名以接收对IMksLibrary实例的引用,以便测试代码可以提供它的模拟
  2. 可以使用一些DI框架(例如Spring,Guice,CDI等)或作为构造函数参数,而不是在process方法内部创建引用来注入对类的引用。
  3. 在类中创建一个名为getIMjsLibraryInstance()之类的受保护方法,该方法将返回MksLibFactory.getDefault() ,并使用它代替显式代码(这是当今大多数IDE可以自动完成的Extract Method重构) 。 在测试代​​码中,您需要创建一个子类(这是我最不喜欢的方法的原因),该子类将覆盖此方法并返回一个模拟,然后测试该子类而不是真实类。 请注意,这是您应该子类化的唯一方法

您可能会因为使用第三个方法而感到沮丧,因为实际上,您并没有真正在测试要测试的类(而是它的子类)。 我倾向于同意这有床味。 但是,请记住,与其他两种方法不同,这不需要对类的客户端进行任何更改(这是支持它的一个非常有力的论据)。

您可以使用其他方法,但是它们本质上与前两种方法非常相似,并且还需要对代码进行一些更改。

如果您觉得任何“常规”测试方法都不够好(由于代码更改或任何其他原因),欢迎您看一下PowerMock ,它将使您能够拦截返回IMksLibrary的静态方法调用实例,然后返回一个模拟。 不过要小心。 当使用这些类型的解决方案时,会发生一些严重的耦合,因此通常不建议您这样做,除非您真的很需要。

暂无
暂无

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

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