Sure, here’s the translation: 如何测试具有非空外键约束的实体

huangapple go评论61阅读模式
英文:

How to test entities which have not null foreign key constraints

问题

我有十几个类似Product, Category, Customer, Order等的表格...
它们之间有not null的关联关系。我创建了ORM,现在正在进行测试。

然而,我觉得这相当繁琐,因为为了测试例如必须属于CustomerOrder实体(即执行persist操作),我还必须创建Customer实例。更进一步:因为Order不能单独存在于Product之外,所以我必须创建Product并将其添加到Order中。Product必须属于某个Category,依此类推。因此,您可以看到一系列强制性关系,这使得测试单个实体变得非常困难。

自然的解决方案是将约束检查推迟到提交时(Oracle):

alter session set constraints=deferred;

然而,我发现了一些信息,即Hibernate不关心推迟约束(支持延迟约束)。

这是否意味着持久性测试必须如此麻烦,还是我可以做得更好/不同?

我认为数据库约束是神圣的,所以因为Hibernate不支持而放弃它们听起来不太好。

英文:

I have a dozen of tables like Product, Category, Customer, Order, ...
with not null relationships to one another. I created ORM and right now I am in the middle of tests.

However I find it pretty tedious, because in order to test for example Order entity which has to belong to Customer (namely perform persist operation) I have to create Customer instance as well. Lets go further: because Order cannot exist separately to Product I have to create Product and add it to Order. Product has to be in some Category, and so on. So you can see a chain of mandatory relationships, which makes testing individual entity very difficult.

Natural solution would be to defer constraint check to commit (Oracle):

alter session set constraints=deferred;

However I found a piece of information that Hibernate doesn't care of deferring (support for deferred constraint).

Does it mean, that persistence testing has to be so problematic or I can do it better/different?

I believe that db constraints are sacred, so resigning from them, because hibernate does not support it sounds bad.

答案1

得分: 2

你可以为测试目的创建工厂。它们的任务是创建一个有效的对象图。这样的类可以在任何类型的测试中使用(不仅限于存储库):

ProductFactory.withType(...).withOtherImportantOption(...).create()

如果你愿意,这样的工厂可以利用随机化,但这并不是强制性的。尽管对于具有唯一约束的字段,必须引入一定程度的随机化。

PS:不满足FK似乎是错误的路径 - 最终你将需要测试持久化许多对象,甚至可能提交事务。而且你可能还想测试级联操作。

英文:

You can create factories for test purposes. Their job is to create a graph of objects that are valid. Such class can be used in any kind of testing (not only the repositories):

ProductFactory.withType(...).withOtherImportantOption(...).create()

Such factory could leverage randomization if you wish, but it's not mandatory. Though some amount of randomization will have to be introduced for fields with unique constraints.

PS: not satisfying FK seems like a wrong path - you'll eventually need tests that persist many objects, maybe even commit transactions. And you may also want to test cascades.

答案2

得分: 1

为什么不创建一个预先填充了大量测试数据的测试数据库。

您可以在名为import.sql的文件中定义测试数据,或者通过javax.persistence.sql-load-script-source指定,它将由模式导出工具自动加载。

更新:明确一下,您只需要在每个表中添加几行测试数据,以便在测试对象时建立有效的引用。

例如,如果您想测试持久化一个Book,您可以这样写:

Book b = new Book();
b.setTitle("Feersum Endjin");
b.setAuthor(em.getReference(Author.class, AUTHOR_ID));
em.persist(b);

其中AUTHOR_ID是测试数据行的ID。

我认为这比编写使用不一致状态的对象(即具有空属性)和违反数据库约束的测试数据的测试要好得多。

英文:

Why not just create your test database prepopulated with a bunch of test data.

You can define test data in a file named import.sql, or specified via javax.persistence.sql-load-script-source, and it will be automatically loaded by the schema export tool.

UPDATE: To be clear, you only need a couple of rows of test data in each table, that you'll use in order to set up valid references from the objects you're testing.

For example, if you want to test persisting a Book, you would write:

Book b = new Book();
b.setTitle("Feersum Endjin");
b.setAuthor( em.getReference(Author.class, AUTHOR_ID) );
em.persist(b);

Where AUTHOR_ID is the id of a row of test data.

This is a lot better, IMO, than writing tests that work with objects in an inconsistent state (i.e. with null attributes) and test data that violates the database constraints.

答案3

得分: 0

如果您正在使用JPA,那么您的存储库将自动进行测试。如果您真的需要,那么请在此处查看。

希望这回答了您的问题。

英文:

If you're using JPA, then your repositories are tested automatically. If you really need to, then have a look here.

Hope this answers your question.

huangapple
  • 本文由 发表于 2020年7月31日 21:43:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/63193025.html
  • database
  • hibernate
  • java
  • spring-data-jpa
  • testing

如何在使用map时避免覆盖for循环中的List(Object[])部分。 go 56
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定

  • 开发者交流平台

    本页二维码