用Java隔离单元测试

时间:2013-11-18 00:17:18

标签: java unit-testing

我刚刚开始使用Java,而且我对如何对Java类进行单元测试同时仍然保持一切孤立感到困惑。具体来说,我想知道在这个例子中我如何测试像createProgram这样的方法:

package com.example.app;

import javax.jdo.JDOHelper;
import javax.jdo.PersistenceManager;
import javax.jdo.PersistenceManagerFactory;

import com.example.data_models.Program;

public class ProgramCreator {
    private PersistenceManagerFactory pm_factory;

    public ProgramCreator(PersistenceManagerFactory pm_factory) {
        this.pm_factory = pm_factory;
    }

    public void createProgram(String name, String instructor, double price) {
        PersistenceManager pm = getPersistenceManager();

        try {
            pm.makePersistent(new Program(name, instructor, price));
        } finally {
            pm.close();
        }
    }

    private PersistenceManager getPersistenceManager()
    {
        return this.pm_factory.getPersistenceManager();
    }
}

我很确定我可以使用类似mockito的库来模拟持久性管理器工厂,并使用它来测试makePersistent方法是否使用正确的参数进行调用,但我该怎么做检查程序数据模型的字段是否正确,同时仍保持一切隔离?我不想依赖程序对象的getter方法,因为这会导致ProgramCreator的单元测试依赖于Program类是正确的。在这种情况下我该怎么办? (使用Ruby,我可能只是删除了new类的Program方法。在Java中是这样的吗?)

3 个答案:

答案 0 :(得分:1)

单元in不一定限于单个类,它是一起工作的最小类。因此,在测试Program时使用ProgramCreator中的getter并没有错。

答案 1 :(得分:1)

通过在 createProgram 方法中创建对象(程序),您将在对象之间创建紧密耦合。而是将创作工作委托给工厂,您可以在单元测试中模拟工厂。这意味着我们只会测试 createProgram 方法正在做什么,而不测试其他方法。尝试单元测试代码可以让我们重新设计/重新考虑代码。

public class ProgramCreator {
    private PersistenceManagerFactory pm_factory;
    private ProgramFactory p_factory;

    public ProgramCreator(PersistenceManagerFactory pm_factory, ProgramFactory pFactory) {
        this.pm_factory = pm_factory;
        this.p_factory = pFactory;
    }

    public void createProgram(String name, String instructor, double price) {
        PersistenceManager pm = getPersistenceManager();
        try {
            pm.makePersistent(p_Factory.createProgram(name, instructor, price));
        } finally {
            pm.close();
        }
    }
}

答案 2 :(得分:0)

您无需在任何地方测试所有内容。

按照你的说法操作:模拟测试createProgram的相应代码,看看它的结果是否与你期望的一样(也就是说:已经有一个程序持久存在于给定的字段中)。

您无需测试实际创建具有这些字段的新Program。您也可以使用其他方法测试new Program(name, instructor, price)是否使用正确的值创建新对象。

关于单元测试最重要的部分是这个流程:

- >总体思路
- >逻辑执行了 - >达到最终状况

你的情况填补了这个

- >我想用变量X,Y和Z来测试createProgram - > ??
- >数据库应返回具有值X,Y和Z

的程序

只要最终结果有效,你就不会在第二步中发生什么。因此,您可以在代码中允许更基本的执行逻辑测试,并检查所有结果是否等于您想要的输出。

这个问题的明显问题是:在出现错误的情况下,这是不是意味着我必须手动调试才能找到问题?是的,它确实。这就是为什么你应该添加许多较小的测试(比如测试构造函数)来帮助查明确切的问题。

使用getter和setter肯定没有问题。事实上,你肯定会需要它们。它是关于测试工作流程,不一定是测试孤立的方法。