我正在使用spring-boot应用程序,我正在构建服务和存储库单元测试。
我知道我可以在扩展JpaRepository的标准存储库中自动装配,但是使用@Repository
注释使用@PersistentContext
和EntityManager
执行em.createNativeQuery(query, Class).getResultList
的标准类呢? }?
例如,我正在运行一个内存数据库,我可以自动装配一个标准的JpaRepository并说getOne
或getAll
,它将针对我的内存测试数据库执行并返回一个结果。
但有没有办法可以对我的SQL存储库执行相同操作并让EntityManger对测试数据库执行nativeQuery?
我还没想出来。
答案 0 :(得分:1)
如果您想使用spring boot对内存数据库执行命名查询,可以使用@DataJpaTest
注释。
这很简单:
1)在pom.xml中包含必要的依赖项
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<version>1.5.3.RELEASE</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>test</scope>
<version>1.4.194</version>
</dependency>
2)注释您的测试类:
@RunWith(SpringRunner.class)
@DataJpaTest
@ContextConfiguration(classes = InCaseYouWantConfigurationConfig.class)
public class TestDemo {
3)自动装配您的存储库或实体管理器(进行测试):
@Autowired
private UserRepository userRepository;
@Autowired
private TestEntityManager entityManager;
4)假设您有一个名为user的实体。创建一个并使用实体管理器来查找它:
@Test
public void testNoDb() {
User user = new User();
user.setFirstName("First Name");
user.setLastName("Last name");
user.setUsername("username");
user.setPassword("password");
user.setEmail("user@email.com");
this.userRepository.save(user);
Query q = this.entityManager.getEntityManager().createQuery("SELECT u From User u WHERE u.username = :username",
User.class);
q.setParameter("username", "username");
User foundUser = (User) q.getSingleResult();
Assert.assertEquals("user@email.com", foundUser.getEmail());
}
在这种情况下,我使用普通查询,但当然您可以定义命名查询并使用entityManager.createNamedQuery(...)
。
答案 1 :(得分:0)
我觉得我没有正确地说出我的问题。但我找到了我需要的答案。
我有一个非JPA存储库,如下所示:
@Repository
public class myRepo {
@PersistentContext
private EntityManager em;
public List findMyObjects(){
String query = <some complicated SQL query>;
return this.em.creatNativeQuery(query, "name of a SqlResultsetMapping").getResultList();
}
}
然后,在我的单元测试中,我有以下内容:
@RunWith(SpringRunner.class)
@SpringBootTest(properties = {"spring.jpa.hibernate.ddl-auto="})
@DataJpaTest
@Sql(<my sql files>)
public class MyRepoTest{
@Autowired
private EntityManager em;
private myRepo repo;
@Before
public void setUp(){
try{
Field f1 = repo.getClass().getDeclaredField("em");
f1.setAccessible(true);
f1.set(repo, em);
}
catch(Exception e){}
}
@Test
public void doMyTest(){
repo.findMyObjects()
}
}
这最终对我有用。 在创建原始帖子之前,我一直在尝试DeiAndrei提到的内容,但是EntityManager对象没有被初始化,没有任何方法可行。也许这是由于我在这个应用程序中配置了其他内容的方式,但我希望这将有助于其他人。