Unit testing JPA/持久性的单元测试

Unit testing JPA/持久性的单元测试,unit-testing,testing,tdd,persistence,Unit Testing,Testing,Tdd,Persistence,如何/将如何测试构建在持久性引擎上的超简单方法。我将使用JPA,但我确信任何持久性机制都有它的等价物 例如 @Entity public class Category { @Id @GeneratedValue private long id; @NotNull @NotEmpty private String name; @NotNull @ManyToOne private User user; //...Getters/Setters

如何/将如何测试构建在持久性引擎上的超简单方法。我将使用JPA,但我确信任何持久性机制都有它的等价物

例如

@Entity
public class Category {

   @Id @GeneratedValue
   private long id;

   @NotNull @NotEmpty
   private String name;

   @NotNull
   @ManyToOne
   private User user;

   //...Getters/Setters...
}

@Stateless
public void CategoryServiceImpl implements CategoryService {

   @PersistenceContext EntityManager entityManager;
   public void addCategory(Category input) {
      entityManager.persist(input);
   }
}

什么样的测试对addCategory有用。我可以看到TDD和单元测试的有用性,但是我不确定对于这样的简单方法应该做什么样的测试。不是真的在寻找“如何”创建测试,而是“测试什么”。

一种哲学是对单元测试非常严格(在我解释我的意思之前,让我说我自己很少遵循这种哲学)。您正在测试这个单元是否完成了它应该做的事情,而不是任何依赖软件(比如持久性机制)是否正常工作

因此,您的这个方法接收一个参数“input”,并将其传递给entityManager.persist。这就是我的工作。因此,我们使用某种模拟框架来获得一个模拟entityManager,并验证传递给addCategory调用的参数是否确实被entityManager接收。就这样。我们已经测试了该方法的所有责任

在更复杂的场景中,这种方法非常有用,您可以测试方法中的所有条件,并发现各种各样的“逐个关闭”和误用空引用错误等

对于这个例子,我不相信我们会找到有趣的bug。 因此,我将使用real EntityManager来设置一些测试套件,这些测试将推动数据的边界。是的,这不是真正的“单元”测试,但我不在乎——我想找到缺陷

例如:

Create a category object with an empty name

Call Add Category
该怎么办?我假设我们打算抛出一个异常?所以我们测试了,事实上,这就是发生的事情

还有一些测试:

  • 插入,然后检索-验证所有字段
  • 插入,然后插入一个副本,我们预期会出现什么错误

  • 诸如此类。

    不需要对现有数据库进行集成测试,您可以通过对嵌入式内存数据库(如h2)运行测试来执行适当的单元测试,h2已配置为根据连接上的注释创建其所有表。对于一个大约有两百个表的数据库来说,这非常有效。

    在命名事物的更广泛世界中,这是“集成”测试吗?@Drew,是的,这是一种集成测试。我想说的是,关于集成测试的一种常见的思考方式更关注于集成我们刚刚开发的模块,而不是基础架构代码。在这里,我们可能会特别关注一个单位的行为,仔细观察其角落案例。