Man*_*dan 4 java spring-boot spring-boot-test
拥有一个 Spring Boot 应用程序,使用 Spring Data JPA 和 H2 配置,用于示例/学术目的。
存储库定义为:
public interface PersonaRepository extends CrudRepository<Persona, String> {
}
Run Code Online (Sandbox Code Playgroud)
然后进行以下测试
@ActiveProfiles(profiles={"h2"})
@DataJpaTest
class PersonaRepositorySliceTests {
@Autowired
private PersonaRepository personaRepository;
@Autowired
private TestEntityManager testEntityManager;
@Test
void countTest() {
long count = personaRepository.count();
assertThat(count).isEqualTo(33);
count = testEntityManager.getEntityManager()
.createQuery("SELECT COUNT(*) FROM Persona p")
.getResultList().size();
System.out.println("count: " + count);//prints 1
//assertThat(count).isEqualTo(33);//fails
count = testEntityManager.getEntityManager()
.createNativeQuery("SELECT COUNT(*) FROM persona")
.getResultList().size();
System.out.println("count: " + count);//prints 1
assertThat(count).isEqualTo(33);//fails
}
}
Run Code Online (Sandbox Code Playgroud)
这
long count = personaRepository.count();
assertThat(count).isEqualTo(33);
Run Code Online (Sandbox Code Playgroud)
通过,因此@Entity检测到了类,当然脚本schema-h2.sql也data-h2.sql按预期执行了。
现在的困惑是为什么
.createQuery("SELECT COUNT(*) FROM Persona p").createNativeQuery("SELECT COUNT(*) FROM persona")有效但总是返回 1,为什么不返回 33 是怎样的预期?
“似乎”TestEntityManager在某种程度上不适用于文件加载的数据data-h2.sql。
次要问题:
即使是yes,为什么返回1而不是0?或者是强制的额外配置?
我读了一些关于@DataJpaTest和 的教程TestEntityManager,其中主要来源:
前者是切片测试,后者是EntityManagerfor测试的替代。在其他教程中,我看到了许多在同一个 中TestEntityManager使用persist并随后检索数据(针对 1 个或多个实体)的示例@Test,因此插入是手动完成的。
主要问题:
TestEntityManager类型(方法)而不是自定义方法呢?CrudRepository<T,ID>根本问题与 Spring Boot/Hibernate 或您的测试设置无关。
SQL 语句SELECT COUNT(*) FROM Person返回单行和单列,其中包含计数的行数:
$ SELECT COUNT(*) FROM Person;
COUNT(*)
----
4
Run Code Online (Sandbox Code Playgroud)
这就是为什么您必须.getSingleResult()从本机或自定义查询的结果中调用的原因:
assertThat(personRepository.count())
.isEqualTo(4);
assertThat(testEntityManager.getEntityManager()
.createQuery("SELECT COUNT(*) FROM Person p", Long.class)
.getSingleResult())
.isEqualTo(4L);
assertThat(testEntityManager.getEntityManager()
.createNativeQuery("SELECT COUNT(*) FROM Person")
.getSingleResult())
.isEqualTo(BigInteger.valueOf(4));
Run Code Online (Sandbox Code Playgroud)
Spring Data JPA 在底层做了完全相同的事情.count():
public long count() {
return (Long)this.em.createQuery(this.getCountQueryString(), Long.class).getSingleResult();
}
Run Code Online (Sandbox Code Playgroud)
您还可以直接注入EntityManager用于@DataJpaTest测试,并且不需要TestEntityManager为此:
@DataJpaTest
class ApplicationTests {
@Autowired
private TestEntityManager testEntityManager;
@Autowired
private EntityManager entityManager;
@Autowired
private PersonRepository personRepository;
@Test
void contextLoads() {
assertThat(personRepository.count())
.isEqualTo(4);
//With TestEntityManager
assertThat(testEntityManager.getEntityManager()
.createQuery("SELECT COUNT(*) FROM Person p", Long.class)
.getSingleResult())
.isEqualTo(4L);
assertThat(testEntityManager.getEntityManager()
.createNativeQuery("SELECT COUNT(*) FROM Person")
.getSingleResult())
.isEqualTo(BigInteger.valueOf(4));
//With EntityManager
assertThat(entityManager.createQuery("SELECT COUNT(*) FROM Person p", Long.class)
.getSingleResult())
.isEqualTo(4L);
assertThat(entityManager.createNativeQuery("SELECT COUNT(*) FROM Person")
.getSingleResult())
.isEqualTo(BigInteger.valueOf(4));
}
}
Run Code Online (Sandbox Code Playgroud)
它TestEntityManager提供了辅助方法,例如使用单行执行持久/刷新/查找操作(刷新内存中的持久上下文并从数据库中读取相同的实体)。这TestEntityManager从来都不是强制性的。
| 归档时间: |
|
| 查看次数: |
6499 次 |
| 最近记录: |