Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/324.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 用Mockito模拟JPA标准生成器_Java_Jpa_Mockito_Criteria Api_Jmock - Fatal编程技术网

Java 用Mockito模拟JPA标准生成器

Java 用Mockito模拟JPA标准生成器,java,jpa,mockito,criteria-api,jmock,Java,Jpa,Mockito,Criteria Api,Jmock,对于我想迁移到Mockito的JPA查询,我有一个特别讨厌的JMock checking()块: Mockery jMock = new Mockery(); final EntityManager fakeEntityManager = jMock.mock(EntityManager.class); final CriteriaBuilder fakeCriteriaBuilder = jMock.mock(CriteriaBuilder.class); final CriteriaQuer

对于我想迁移到Mockito的JPA查询,我有一个特别讨厌的JMock checking()块:

Mockery jMock = new Mockery();
final EntityManager fakeEntityManager = jMock.mock(EntityManager.class);
final CriteriaBuilder fakeCriteriaBuilder = jMock.mock(CriteriaBuilder.class);
final CriteriaQuery<String> fakeCriteriaQuery = jMock.mock(CriteriaQuery.class);
jMock.checking(new Expectations() {{
    oneOf(fakeEntityManager).getCriteriaBuilder(); will(returnValue(fakeCriteriaBuilder));
    oneOf(fakeCriteriaBuilder).createQuery(String.class); will(returnValue(fakeCriteriaQuery));
    oneOf(fakeCriteriaQuery).from(Archiveusergrouplicences.class);
    oneOf(fakeCriteriaQuery).select(with(any(Selection.class)));
    oneOf(fakeCriteriaBuilder).isNotNull(with(any(Expression.class)));
    oneOf(fakeCriteriaQuery).where(with(any(Expression.class)));
    oneOf(fakeEntityManager).createQuery(fakeCriteriaQuery);
    // Return an empty resultset
}});
mockry jMock=newmockry();
最终EntityManager fakeEntityManager=jMock.mock(EntityManager.class);
final-CriteriaBuilder-fakeCriteriaBuilder=jMock.mock(CriteriaBuilder.class);
final-CriteriaQuery-fakeCriteriaQuery=jMock.mock(CriteriaQuery.class);
jMock.checking(新期望值(){{
getCriteriaBuilder();will(returnValue(fakeCriteriaBuilder));
createQuery(String.class);will(returnValue(fakeCriteriaQuery));
其中一个(fakeCriteriaQuery).from(archiveUserGroupLicenses.class);
(fakeCriteriaQuery)中的一个。选择(使用(any)(Selection.class));
其中一个(fakeCriteriaBuilder).isNotNull(带有(any(Expression.class)));
其中之一是(fakeCriteriaQuery).where(带有(any(Expression.class));
创建查询(fakeCriteriaQuery);
//返回一个空的结果集
}});
正在测试的代码如下所示:

CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<String> criteria = builder.createQuery(String.class);

Root<Archiveusergrouplicences> institution = criteria.from(Archiveusergrouplicences.class);
criteria.select(institution.get(Archiveusergrouplicences_.usergroupid));    
criteria.where(builder.isNotNull(institution.get(Archiveusergrouplicences_.usergroupid)));

List<String> result = entityManager.createQuery(criteria).getResultList();
CriteriaQuery<String> fakeCriteriaQuery = mock(CriteriaQuery.class, RETURNS_DEEP_STUBS);
when(entityManager.createQuery(anyString())).thenReturn(fakeCriteriaQuery);
CriteriaBuilder=entityManager.getCriteriaBuilder();
CriteriaQuery criteria=builder.createQuery(String.class);
Root,这在某种程度上解决了模拟的CriteriaBuilder部分;但是我的主要问题是使用mock对象作为另一个mock-Mockito的.thenReturn()值似乎不允许这样做。例如,对于行:

CriteriaQuery<String> criteria = builder.createQuery(String.class);
CriteriaQuery-criteria=builder.createQuery(String.class);
我想返回模拟CriteriaQuery对象,如下所示:

CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<String> criteria = builder.createQuery(String.class);

Root<Archiveusergrouplicences> institution = criteria.from(Archiveusergrouplicences.class);
criteria.select(institution.get(Archiveusergrouplicences_.usergroupid));    
criteria.where(builder.isNotNull(institution.get(Archiveusergrouplicences_.usergroupid)));

List<String> result = entityManager.createQuery(criteria).getResultList();
CriteriaQuery<String> fakeCriteriaQuery = mock(CriteriaQuery.class, RETURNS_DEEP_STUBS);
when(entityManager.createQuery(anyString())).thenReturn(fakeCriteriaQuery);
CriteriaQuery fakeCriteriaQuery=mock(CriteriaQuery.class,返回\u DEEP\u存根);
when(entityManager.createQuery(anyString())。然后return(fakeCriteriaQuery);
这会引发语法错误:

类型OnGoingStubing中的方法thenReturn(Query)不可用 适用于参数(CriteriaQuery)


我该如何测试这段代码,或者改进它以使其更易于测试?

就像您jMock CriteriaQuery一样

final CriteriaQuery<String> fakeCriteriaQuery = jMock.mock(CriteriaQuery.class);
final-CriteriaQuery-fakeCriteriaQuery=jMock.mock(CriteriaQuery.class);
您还需要模拟标准查询

final CriteriaQuery<String> fakeCriteriaQuery = mock(CriteriaQuery.class);
final-CriteriaQuery-fakeCriteriaQuery=mock(CriteriaQuery.class);

事实证明,只要设置了正确的参数,就可以从其他模拟返回模拟!我试图断言:

when(entityManager.createQuery(anyString())).thenReturn(fakeCriteriaQuery);
当我真正想通过一门课时:

when(fakeCriteriaBuilder.createQuery(String.class)).thenReturn(fakeCriteriaQuery);
这个错误是莫基托神秘地告诉我我把我的期望搞糟了


然而,我可能会考虑重写这个测试,而不是翻译最初编写的内容。有人指出,;通常最好避免以这种方式模拟库,并且检查的条件相当模糊。

我要问自己的问题是,模拟整个ORM是否真的值得,或者是否可以更容易地使用内存中的数据库进行测试。所有其他测试都是功能性的(使用测试数据库和类似于dbunit的东西)。我正在迁移的测试的目的似乎是断言,当发生意外异常时,DAO将向调用方返回NoResultsException。我认为异常情况取决于一些场景,比如数据库在查询过程中发生故障,或者在被测试的情况下:JPA框架返回一个NPE。在执行查询之前使用func测试并删除表可能是比强制NPE更好的方法@布莱斯:谢谢你的指点。正如我在对问题本身的评论中指出的那样,我觉得这是个坏主意。现在,我有一些参考来支持这种感觉。再次感谢!谢谢你的回答,但我已经在嘲笑CriteriaQuery(请参阅我的代码)。这个特殊的测试是一个完整的集成测试套件的边缘案例。是的,如果你认为这是不可能的,那么你真的应该考虑编写集成测试。若这是既不能在集成测试中使用也不能在集成测试中使用的遗留代码,那个么在代码中使用间接寻址,比如包装器。但我的建议是坚持这条路线,否则以后可能会给你带来沉重打击!Mockito有一个名为“RETURNS\u DEEP\u STUBS”的默认答案,尽管它对构建器API并没有真正的用处。另外,mock返回一个mock就像一种测试气味,您的单元测试和方法实现耦合太多,这是白盒测试!我强烈建议您考虑集成测试,例如H2。JPA的JSR专家成员Antonio Goncalves就此事写了一篇有趣的文章