我有一个Spring项目,我想测试一些查询。我希望插入一组预定义的数据,并执行Repository查询,以检查所需的结果。
为此,我使用内存中的H2 DB,问题(我认为)并不存在,与DB相关的一切都是正常的。主要问题是,我无法正确地模拟存储库中的EntityManager字段,而且查询始终为null。
我的存储库如下:
@Repository
public class MyRepositoryImpl implements MyRepository {
@PersistenceContext
private EntityManager entityManager;
@Override
public Result runQuery() {
TypedQuery<Result> query = entityManager.createQuery(
"SELECT ...", Result.class);
return query.setParameter("...", "...") // here 'query' is always null
.setMaxResults(1)
.getResultStream()
.findFirst()
.orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Entity not found"));
}
}在测试之外执行时,它工作得很好,但是尝试运行这个测试文件会引发一个错误:
@RunWith(SpringRunner.class)
public class MyRepositoryTest {
@Mock
EntityManager entityManager;
@InjectMocks
MyRepositoryImpl repository;
@Test
public void it_should_works() {
Result r = repository.runQuery();
assertNull(r);
}
}存储库是模拟的,不是空的,我可以调用该方法。但是在存储库中,由于query字段是空的,所以当尝试执行时,它会抛出一个NullPointerException。
我在互联网上搜索过,我找到了很多方法来测试界面中的JPARepository和@Query,但没有一个EntityManager查询。
此外,我还找到了一些方法来模拟查询的结果,比如when(runQuery()).thenReturn(result),但我不想那样,我在内存DB中有数据,所以我想执行查询并获得结果。
因此,我认为现在的主要问题是如何在存储库类中正确地模拟EntityManager对象。
提前谢谢。
编辑:
我一直在关注此链接,就像另一个这样的问题:它只是在嘲弄JpaRepository。
我使用了这个代码:
@Test
public void it_should_works() {
Result r = repository.findAll();
assertNotNull(r);
}并且工作得很好,但是使用我自己的查询时出错了:
org.springframework.orm.jpa.JpaSystemException: could not advance using next(); nested exception is org.hibernate.exception.GenericJDBCException: could not advance using next()
...
Caused by: org.h2.jdbc.JdbcSQLNonTransientException: El objeto ya está cerrado
The object is already closed [90007-200]所以问题是:它与我的数据库有关吗?为什么使用JpaRepository方法可以工作,但我自己的查询不起作用?
编辑:
解决了将@Transactional添加到存储库的问题。
发布于 2021-12-22 15:41:21
由于您使用内存中的h2数据库来运行测试,并且您希望在测试中实际使用该数据库,所以您不应该真的在模仿任何东西。
您的模拟不起作用,因为MyRepositoryImpl通常是由Spring初始化的,而且这个过程比插入EntityManager要复杂得多。
我认为你想做的事情更像这里所描述的,https://www.baeldung.com/spring-testing-separate-data-source
因此,您将有一个src/test/resources/application.properties文件,该文件覆盖数据源属性。然后,您只需像普通一样将您的存储库放到测试类中。
https://stackoverflow.com/questions/70450960
复制相似问题