Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/343.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Java中保持单元测试的隔离_Java_Unit Testing - Fatal编程技术网

在Java中保持单元测试的隔离

在Java中保持单元测试的隔离,java,unit-testing,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.Pr

我刚刚开始学习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时,我可能只会删除
程序
类的
新方法。在Java中可能会出现类似的情况吗?

中的一个单元不一定局限于单个类,它是一起工作的最小类集。因此,在测试
ProgramCreator
时使用
Program
的getter没有什么错,您不必到处测试所有内容

照你说的做:模拟适当的代码来测试
createProgram
,看看结果是否与你期望的一样(aka:有一个程序使用给定的字段持久化)

您不必测试您是否实际创建了一个包含这些字段的新
程序。您也可以使用不同的方法测试
新程序(名称、讲师、价格)
是否创建了具有正确值的新对象

单元测试最重要的部分是以下流程:

->总体思路
->执行的逻辑
->结束局势

你的情况填补了这个空缺

->我想用变量X、Y和Z测试
createProgram

->??
->数据库应该返回一个值为X、Y和Z的程序

总之,只要最终结果有效,你并不在乎第二步会发生什么。出于这个原因,您可以在代码中允许更多基本上执行逻辑的通用测试,并检查所有这些测试的结果是否与您期望的输出一致

当然,最明显的问题是:如果出现错误,这是否意味着我必须手动调试才能找到问题?是的。这就是为什么您应该添加许多较小的测试(比如测试构造函数)来帮助确定确切的问题

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

通过在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();
        }
    }
}

但是这不是一个集成测试而不是一个单元测试吗?这并不是我想避免使用getter和setter,而是我想避免测试被测对象以外的任何东西。这肯定更像是一个集成测试,但是对于一个只将一个操作委托给另一个类中的方法的方法,你会确切地测试什么呢?您可以安全地假设,使用几个参数调用方法将按预期工作:将使用这些参数调用该方法。如果您想对这些参数执行逻辑,那么您使用的测试方法是错误的;这种方法没有太多的逻辑。我仍然有点好奇,是否可以在不依赖它创建的类的正确性(
Program
)的情况下测试这样的方法。但是我的对象不会耦合到工厂吗?我也需要在这里使用依赖注入吗?@Ajedi32是的,程序工厂的依赖注入应该是解决这个问题的方法。我已经编辑了上面的回复,以澄清问题。嗯,好吧,听起来很合理。