使用数据进行单元测试的最佳方法

时间:2017-05-22 14:43:30

标签: java hibernate unit-testing junit

我需要在Spring项目上测试很多DAO类。

我已经使用 DBUnit 来模拟我的数据库,但是我使用@Before注释创建对象并在创建/更新/删除操作测试后对它们进行比较。

@DatabaseSetup(value = { "/db_data/dao/common.xml", "/db_data/dao/myDAOCommonTest.xml" })
@DbUnitConfiguration(dataSetLoader = ReplacementDataSetLoader.class)
public class MyDAOImplTest extends AbstractDaoTU {

  @Autowired
    private MyDAO myDAO;

    private Set<ClassNeeded> objectsNeeded = new HashSet<>();
    private ClassOne classOne;
    private ClassTwo classTwo;

    private ClassThree classThree;

    @Override
    public void setUp() throws Exception {
        super.setUp();
        this.objectsNeeded.add(somethingComingFromTheMotherClass);

        this.classOne = new ClassOne();
        this.classOne.setIdClassOne(1L)
    this.classOne.setObjectsNeeded(this.objectsNeeded);
        // ... Many other sets

        this.classTwo = new ClassTwo();
        this.classTwo.setIdClassTwo(1L);
    this.classTwo.setClassOne(this.classOne);
    // ... Many other sets

    // ... Other sets follow for a lot of other objects
    }

  @Test
  public void testOne {
    // ...
  }

  // ... Other tests follow
}

我正在使用ORM(在这种情况下是Hibernate),并且大多数对象是相互依赖的。我的dao函数主要需要调用完整的对象,所以我必须在测试之前创建对象。

我的问题如下:

  • 单元测试DAO有更好的方法吗?
  • 您知道哪些工具可以更容易/更快地编写? (我正在使用maven进行包装)

感谢您的帮助!

2 个答案:

答案 0 :(得分:2)

  1. 数据库单元使测试的维护变得复杂,因为它增加了更改时需要更新的位置数。此外,它将数据准备与测试分开太多,因此很难找到哪些数据与哪些测试相关。
  2. 理想情况下,每项测试都会为自己准备数据。这将删除全局状态并将相关事物保持在一起。
  3. 准备数据只需创建实体并将它们保存在同一个测试中。您可以使用随机化和事务回滚来隔离测试。以下是我的一个项目中的示例:

    @Test public void returnsExperimentAsItWasSaved() {
        Experiment original = Experiment.random();
        experimentRepository.save(original);
        flushToDbAndClearCache();
    
        Experiment fromDb = experimentRepository.findOne(original.getExperimentId());
        assertReflectionEquals(original, fromDb);
    }
    

    请注意,使用完全相同的DAO类来准备数据。

答案 1 :(得分:1)

最好的方法是像开发代码一样开发测试:重构以最小化重复,提取可重用服务等。

因此,您可能会创建一些TestCaseFactory来链接整组对象并使用您的实际DAO保存它们。然后,你可以像@Before一样打电话给他们。如果需要许多不同的对象集,可以创建不同的方法或参数对象等。

并在@After中清除所有测试数据。