Spring / Hibernate自动装配用于单元测试的非JPA存储库

时间:2017-11-22 00:56:13

标签: java spring hibernate jpa

我正在使用spring-boot应用程序,我正在构建服务和存储库单元测试。

我知道我可以在扩展JpaRepository的标准存储库中自动装配,但是使用@Repository注释使用@PersistentContextEntityManager执行em.createNativeQuery(query, Class).getResultList的标准类呢? }?

例如,我正在运行一个内存数据库,我可以自动装配一个标准的JpaRepository并说getOnegetAll,它将针对我的内存测试数据库执行并返回一个结果。

但有没有办法可以对我的SQL存储库执行相同操作并让EntityManger对测试数据库执行nativeQuery?

我还没想出来。

2 个答案:

答案 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对象没有被初始化,没有任何方法可行。也许这是由于我在这个应用程序中配置了其他内容的方式,但我希望这将有助于其他人。

相关问题