测试一个使用mockito调用private void方法的方法

时间:2014-06-25 04:29:55

标签: java mocking 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()方法编写mockito测试用例。调用initialize(mksConnectionParam, MksLibFactory.getDefault())时测试失败。这是因为在这个过程中我们调用真正的mks连接,并且我传递虚拟用户名和密码。 我们无法模拟这种初始化方法。有没有办法做到这一点?

小伪代码会有很大的帮助。

之前我将方法初始化为private。将它更改为public会有什么不同吗?

1 个答案:

答案 0 :(得分:0)

有几种方法可以测试这种情况,不同的人会提倡不同的方法,主要是基于个人偏好。

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

回到常规测试方法,问题是你使用真正的IMksLibrary而不是模拟,那是因为你在process方法中获得了对它的引用。以下是您可能需要考虑的一些方法:

  1. 更改process方法的签名以接收对IMksLibrary实例的引用,以便测试代码可以提供对它的模拟
  2. 不是在process方法中创建引用,而是通过使用一些DI框架(例如Spring,Guice,CDI等)或作为构造函数参数来注入对类的引用
  3. 在类中创建一个名为getIMjsLibraryInstance()的受保护方法,它将返回MksLibFactory.getDefault(),并使用它而不是显式代码(这是Extract Method重构,可以自动生成现在由大多数IDE for Java完成)。在测试代​​码中,您需要创建一个子类(这就是为什么它是我最不喜欢的方法),它会覆盖此方法并返回一个mock,并测试子类而不是真正的类。请注意,这是您应该继承的 ONLY 方法
  4. 您可能会觉得无法使用第三种方法,因为实际上,您并没有真正测试您要测试的类(而是它的子类)。我倾向于同意这有一种床味。但是,请记住,与其他两种方法不同,这不需要对类的客户端进行任何更改(这是一个非常有利于它的论据)。

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

    如果您认为任何“常规”测试方法不够好(由于代码更改或其他原因),欢迎您查看PowerMock,这样您就可以拦截静态方法调用,返回IMksLibrary实例,并返回模拟。但要谨慎一点。使用这些类型的解决方案时会发生一些严重的耦合,因此通常不会强烈推荐,除非您真的非常需要。