如何模拟querydsl查询?
Posted
技术标签:
【中文标题】如何模拟querydsl查询?【英文标题】:How to mock querydsl query? 【发布时间】:2021-11-26 10:35:33 【问题描述】:在我的产品代码中,我有以下 queryDsl 查询:
Collection<String> myList = new ArrayList<>();
myList.add("blue");
myList.add("green");
myList.add("yellow");
QAnimal qAnimal = QAnimal.animal;
return animalRepository.exists(
qAnimal.color.in(myList).and(
qAnimal.name.eq("animal_name")
)
);
我想使用 Mockito 模拟这个 queryDsl 查询。在我的测试文件中,在我所做的设置方法中:
Collection<Book> myList = new ArrayList<>();
myList.add("blue");
myList.add("green");
myList.add("yellow");
QAnimal qAnimal = QAnimal.animal;
when(qAnimal.color.in(myList)).thenReturn((Expressions.asBoolean(false)));
when(qAnimal.name.eq("animal_name")).thenReturn((Expressions.asBoolean(true)));
运行测试时,我收到以下问题:
org.mockito.exceptions.misusing.MissingMethodInvocationException:
when() requires an argument which has to be 'a method call on a mock'.
For example:
when(mock.getArticles()).thenReturn(articles);
Also, this error might show up because:
1. you stub either of: final/private/equals()/hashCode() methods.
Those methods *cannot* be stubbed/verified.
2. inside when() you don't call method on mock but on some other object.
我无法创建 JPAQuery 对象,只能使用那种查询。
【问题讨论】:
【参考方案1】:你为什么要嘲笑JPAQuery
?此时,您要么测试 Querydsl 的内部结构,要么确保您编写了您所写的内容。只需模拟整个 AnimalRepository
即可。如果您想正确测试animalRepository
,最好在实际执行针对数据库的查询的集成测试中这样做。也可以使用querydsl-collections
对模拟数据执行查询。
如果您坚持使用 Mockito 存根模拟 JPAQuery
,那么模拟构建器 API(例如 JPAQuery
)的最简单方法是使用 Answers.RETURNS_SELF
作为默认存根。
例如,使用以下代码来实例化您的queryMock
:
@Mock(answer = Answers.RETURNS_SELF) JPAQuery queryMock;
【讨论】:
我想我被误解了。我不想模拟 JPAQuery,我想从第一个 sn-p 模拟 querydsl 代码,我得到了那个错误qAnimal.color
是静态和字段,Mockito 不能真正模拟静态和字段,主要是方法调用。然而,正因为如此,根本不需要模拟qAnimal.color.in(myList).and(qAnimal.name.eq("animal_name"))
,而是模拟animalRepository.exists(any())
。
但是如果我想为 animalRepository.exists( .. )
返回不同的案例怎么办?比如有时我想返回false,有时返回true? animalRepository.exists(any())
总是返回相同的东西(真或假)
Mockito.when(mock).thenReturn(a, b, c)
采用多个参数作为返回值,分别用于第一次、第二次、第三次等调用。所以不需要使用不同的参数来从存根返回不同的返回值。
听起来是一个很好的解决方法,但在更改测试的输入时可能会很困难。目前,我会坚持这个解决方案,谢谢!以上是关于如何模拟querydsl查询?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 QueryDSL 在查询中使用 SAMPLE 关键字