简体   繁体   English

如何对QueryDSL Criteria生成进行单元测试?

[英]How do I unit test QueryDSL Criteria generation?

I'm using QueryDSL 3.2.4 with Spring Data JPA 1.4.2 serving as my Repository layer. 我将QueryDSL 3.2.4和Spring Data JPA 1.4.2用作我的存储库层。 I have a class to take my web form object (a simple Bean that Spring binds the search form to) and generate the QueryDSL Criteria object for it, which then gets passed to the business/data layer to run the query. 我有一个类来获取我的Web表单对象(Spring将搜索表单绑定到的一个简单Bean)并为其生成QueryDSL Criteria对象,然后将该对象传递给业务/数据层以运行查询。

I'm trying to figure out the best way to unit test this generation of a Criteria object. 我试图找出最好的方法来对这一代Criteria对象进行单元测试。 Depending on what is being searched for, different combinations of fields will be in the query (Basically, the typical search form, where fields can be blank to not constrain based on it, but each non-blank field indicates a search criterion, and some fields may have some additional options such as whether it's for "exact match", "starts with", or "contains".) 根据要搜索的内容,查询中将使用不同的字段组合(基本上是典型的搜索表单,其中的字段可以为空,不以此为基础进行约束,但每个非空白字段均表示搜索条件,有些字段可能还有一些其他选项,例如用于“完全匹配”,“以...开头”还是“包含”。)

There's a Spring Data JPA tutorial which advocates for the use of QueryDSL over JPA Criteria API, in part because one can unit test QueryDSL just by comparing the .toString(). 有一个Spring Data JPA教程 ,提倡在JPA Criteria API上使用QueryDSL,部分原因是可以通过比较.toString()来对QueryDSL进行单元测试。 So, that's the way I'm leaning toward for now, of making sure that the resulting Criteria object's toString() is reasonable for the query I'm trying to test, but I'm not sure how I'd get the "expected" toString without constructing the desired query ahead of time and seeing what its toString is, so it feels like not a great test, and it feels like it's based on the internals of QueryDSL which may be subject to change. 因此,这就是我现在倾向于的方式,确保所得的Criteria对象的toString()对于我要测试的查询而言是合理的,但是我不确定如何获得“预期” “ toString,而无需提前构造所需的查询并查看其toString是什么,因此感觉好像不是一个很好的测试,并且感觉它基于QueryDSL的内部结构,该内部结构可能会发生变化。 (I think of toString on most classes as mainly being a debugging aid, not a part of the spec, though if somebody pointed me to a spec on how QueryDSL creates its toString() methods and that it's part of the way to use and/or test usage of the library, I think I'd be a lot happier with this approach.) I'm hoping there's something better. (我认为大多数类上的toString主要是作为调试工具,而不是规范的一部分,尽管有人指出我关于QueryDSL如何创建其toString()方法的规范,并且这是使用和/的方式的一部分或测试该库的使用情况,我想我会更喜欢这种方法。)我希望有更好的方法。

There's another StackOverflow question " How do I unit test the querydsl query inside the given method? ", but that looks to be about testing entire queries and needing a mock EntityManager. 还有另一个StackOverflow问题“ 如何在给定方法内对querydsl查询进行单元测试? ”,但这似乎是关于测试整个查询并需要模拟EntityManager。 I'm hoping to just test the Criteria part, so I'm hoping there's a simpler approach than that, where I'd need to mock up a Query that's using the Criteria and then a mock EntityManager to use it, and that all looks to me more complicated than what I'm trying to do for just unit testing that I'm creating a Criteria object correctly. 我希望只测试Criteria部分,所以我希望有一种比这更简单的方法,在这种情况下,我需要模拟使用Criteria的Query,然后模拟EntityManager来使用它,并且看起来对我来说,比我要正确创建Criteria对象的单元测试要复杂得多。

I feel like I can't be the only person trying to test that I'm creating the right Criteria. 我觉得我不可能是唯一要测试我正在创建正确标准的人。 Thanks for any insights you may have into what I'm doing wrong or how one can unit test this better. 感谢您对我做错事或如何更好地进行单元测试的任何见解。

I 'unit' test all of my QueryDSL code with a real EntityManager and a real in memory H2 database . 我使用真实的EntityManager和真实的内存H2数据库 “单元”测试所有QueryDSL代码。 No mocking of the EntityManager and no checking the generated JPQL, I test that the query actually returns the objects I expect. 没有对EntityManager的模拟,也没有检查生成的JPQL,我测试查询是否实际上返回了我期望的对象。

The Unit Testing purists could argue that this is not a true unit test but I have code that works and it is quick enough. 单元测试的纯粹主义者可能会认为这不是真正的单元测试,但是我有可以正常工作的代码,而且它足够快。

This is fairly easily achieved with springs embedded database support : 通过springs 嵌入式数据库支持,这很容易实现:

<jdbc:initialize-database data-source="dataSource">
  <jdbc:script location="classpath:com/foo/sql/db-schema.sql"/>
</jdbc:initialize-database>

My approach for this is to start with simple queries and then collect more and more complex "samples". 我的方法是从简单的查询开始,然后收集越来越复杂的“样本”。 Yes, I'm using the actual query result and copy that into the expected part of my unit tests after eyeballing it. 是的,我正在使用实际的查询结果,并将其复制到单元测试的expected部分中。

This isn't a great test; 这不是一个很好的测试。 the purpose is slightly different: It documents what you expect. 目的稍有不同:它记录了您的期望。

When something changes, your tests will start to fail and you can create a diff between "what I expected yesterday" and "what I get today." 当某些事情发生变化时,您的测试将开始失败,并且您可以在“我昨天的期望”和“我今天的期望”之间建立区别。

This also documents what your code is capable of. 这也记录了您的代码的功能。 When a bug in production is discovered, you can try to write a new unit test and see how many others are also failing. 当发现生产中的错误时,您可以尝试编写新的单元测试,并查看还有多少其他失败。 This gives you good understanding of the impact of a change (1 change + 90% of the tests fail? You found a hot spot!) 这使您对更改的影响有很好的了解(1个更改+ 90%的测试失败?您发现了热点!)

When I fix bugs, I start to see patterns what usually goes wrong and I can protect those places with specific unit tests (like in sub builders used by the big query builder). 修复错误后,我开始看到通常会出问题的模式,并且可以使用特定的单元测试来保护这些位置(例如在大型查询构建器使用的子构建器中)。

For a few complex queries, I create unit tests to see if they would actually work. 对于一些复杂的查询,我创建了单元测试以查看它们是否真正起作用。 That gives me the confidence that the quick "string compare" unit tests work. 这使我有信心快速进行“字符串比较”单元测试。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM