【问题标题】:How to test Spring Data repositories?如何测试 Spring Data 存储库?
【发布时间】:2014-06-19 14:21:27
【问题描述】:

我想要在 Spring Data 的帮助下创建一个存储库(例如,UserRepository)。我是 spring-data 的新手(但不是 spring),我使用这个 tutorial。我选择的处理数据库的技术是 JPA 2.1 和 Hibernate。问题是我对如何为这样的存储库编写单元测试一无所知。

我们以create() 方法为例。由于我的工作是先测试,所以我应该为它编写一个单元测试——这就是我遇到三个问题的地方:

  • 首先,如何将EntityManager 的模拟注入UserRepository 接口的不存在实现中? Spring Data 会基于这个接口生成一个实现:

    public interface UserRepository extends CrudRepository<User, Long> {}
    

    但是,我不知道如何强制它使用 EntityManager 模拟和其他模拟 - 如果我自己编写了实现,我可能会有一个 EntityManager 的 setter 方法,允许我使用我的模拟单元测试。 (至于实际的数据库连接,我有一个JpaConfiguration 类,用@Configuration@EnableJpaRepositories 进行注释,它以编程方式为DataSourceEntityManagerFactoryEntityManager 等定义了bean。但存储库应该是test-友好并允许覆盖这些东西)。

  • 其次,我应该测试交互吗?我很难弄清楚应该调用 EntityManagerQuery 的哪些方法(类似于 verify(entityManager).createNamedQuery(anyString()).getResultList();),因为编写实现的不是我。

    李>
  • 第三,我是否应该首先对 Spring-Data 生成的方法进行单元测试?据我所知,第三方库代码不应该进行单元测试——只有开发人员自己编写的代码才应该进行单元测试。但如果这是真的,那么第一个问题仍然会回到现场:比如说,我的存储库有几个自定义方法,我将为此编写实现,我如何注入我的 EntityManager 和 @987654339 的模拟@ 进入最终生成的存储库?

注意:我将使用集成和单元测试测试我的存储库。对于我的集成测试,我使用的是 HSQL 内存数据库,显然我没有使用数据库进行单元测试。

可能还有第四个问题,在集成测试中测试正确的对象图创建和对象图检索是否正确(例如,我有一个用 Hibernate 定义的复杂对象图)?

更新:今天我继续尝试模拟注入 - 我创建了一个静态内部类来允许模拟注入。

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
@Transactional
@TransactionConfiguration(defaultRollback = true)
public class UserRepositoryTest {

@Configuration
@EnableJpaRepositories(basePackages = "com.anything.repository")
static class TestConfiguration {

    @Bean
    public EntityManagerFactory entityManagerFactory() {
        return mock(EntityManagerFactory.class);
    }

    @Bean
    public EntityManager entityManager() {
        EntityManager entityManagerMock = mock(EntityManager.class);
        //when(entityManagerMock.getMetamodel()).thenReturn(mock(Metamodel.class));
        when(entityManagerMock.getMetamodel()).thenReturn(mock(MetamodelImpl.class));
        return entityManagerMock;
    }

    @Bean
    public PlatformTransactionManager transactionManager() {
        return mock(JpaTransactionManager.class);
    }

}

@Autowired
private UserRepository userRepository;

@Autowired
private EntityManager entityManager;

@Test
public void shouldSaveUser() {
    User user = new UserBuilder().build();
    userRepository.save(user);
    verify(entityManager.createNamedQuery(anyString()).executeUpdate());
}

}

但是,运行此测试会给我以下堆栈跟踪:

java.lang.IllegalStateException: Failed to load ApplicationContext
at org.springframework.test.context.CacheAwareContextLoaderDelegate.loadContext(CacheAwareContextLoaderDelegate.java:99)
at org.springframework.test.context.DefaultTestContext.getApplicationContext(DefaultTestContext.java:101)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:109)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:75)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:319)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:212)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:289)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:291)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:232)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:89)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:175)
at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:77)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:195)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:63)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userRepository': Error setting property values; nested exception is org.springframework.beans.PropertyBatchUpdateException; nested PropertyAccessExceptions (1) are:
PropertyAccessException 1: org.springframework.beans.MethodInvocationException: Property 'entityManager' threw exception; nested exception is java.lang.IllegalArgumentException: JPA Metamodel must not be null!
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1493)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1197)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:304)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:300)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:684)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:760)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)
    at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:121)
    at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:60)
    at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.delegateLoading(AbstractDelegatingSmartContextLoader.java:100)
    at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.loadContext(AbstractDelegatingSmartContextLoader.java:250)
    at org.springframework.test.context.CacheAwareContextLoaderDelegate.loadContextInternal(CacheAwareContextLoaderDelegate.java:64)
    at org.springframework.test.context.CacheAwareContextLoaderDelegate.loadContext(CacheAwareContextLoaderDelegate.java:91)
    ... 28 more
Caused by: org.springframework.beans.PropertyBatchUpdateException; nested PropertyAccessExceptions (1) are:
PropertyAccessException 1: org.springframework.beans.MethodInvocationException: Property 'entityManager' threw exception; nested exception is java.lang.IllegalArgumentException: JPA Metamodel must not be null!
    at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:108)
    at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:62)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1489)
    ... 44 more

【问题讨论】:

    标签: unit-testing jpa spring-data-jpa spring-data


    【解决方案1】:

    tl;博士

    简而言之 - 没有办法合理地对 Spring Data JPA 存储库进行单元测试,原因很简单:模拟我们调用以引导存储库的 JPA API 的所有部分很麻烦。无论如何,单元测试在这里没有太大意义,因为您通常不会自己编写任何实现代码(请参阅下面有关自定义实现的段落),因此集成测试是最合理的方法。

    详情

    我们进行了大量的前期验证和设置,以确保您只能引导一个没有无效派生查询等的应用。

    • 我们为派生查询创建和缓存CriteriaQuery 实例,以确保查询方法不包含任何拼写错误。这需要使用 Criteria API 以及 meta.model。
    • 我们通过要求 EntityManager 为这些手动定义的查询创建一个 Query 实例来验证手动定义的查询(这会有效地触发查询语法验证)。
    • 我们检查 Metamodel 以获取有关处理的域类型的元数据,以准备 is-new 检查等。

    您可能会推迟到手写存储库中的所有内容,这可能会导致应用程序在运行时中断(由于无效查询等)。

    如果您考虑一下,您没有为存储库编写代码,因此无需编写任何单元测试。根本没有必要,因为您可以依靠我们的测试库来捕获基本错误(如果您仍然碰巧遇到一个错误,请随时提出ticket)。但是,肯定需要集成测试来测试持久层的两个方面,因为它们是与您的域相关的方面:

    • 实体映射
    • 查询语义(无论如何都会在每次引导尝试时验证语法)。

    集成测试

    这通常是通过使用内存数据库和测试用例来完成的,这些用例通常通过测试上下文框架(正如您已经做的那样)引导 Spring ApplicationContext,预填充数据库(通过插入对象实例通过 @ 987654329@ 或 repo,或通过普通 SQL 文件),然后执行查询方法以验证它们的结果。

    测试自定义实现

    存储库的自定义实现部分是written in a way,他们不必了解 Spring Data JPA。它们是普通的 Spring bean,注入了 EntityManager。您当然可能想尝试模拟与它的交互,但老实说,对 JPA 进行单元测试对我们来说并不是一个太愉快的体验,而且它可以处理很多间接(EntityManager -> @987654332 @、CriteriaQuery 等),这样你最终会得到模拟返回模拟等等。

    【讨论】:

    • 您是否有一个与内存数据库(例如 h2)进行集成测试的小示例的链接?
    • 示例 here 使用 HSQLDB。切换到 H2 基本上就是在 pom.xml 中交换依赖关系。
    • 谢谢,但我希望看到一个预先填充数据库和/或真正检查数据库的示例。
    • “以某种方式编写”后面的链接不再起作用。也许你可以更新它?
    • 那么,您也建议使用集成测试而不是单元测试来进行自定义实现吗?根本不为他们编写单元测试?只是为了澄清。是的话没关系。我理解原因(太复杂而无法模拟所有事情)。我是 JPA 测试的新手,所以我只想弄清楚。
    【解决方案2】:

    使用 Spring Boot + Spring Data 变得相当简单:

    @RunWith(SpringRunner.class)
    @DataJpaTest
    public class MyRepositoryTest {
    
        @Autowired
        MyRepository subject;
    
        @Test
        public void myTest() throws Exception {
            subject.save(new MyEntity());
        }
    }
    

    @heez 的解决方案提供了完整的上下文,这只提供了 JPA+Transaction 工作所需的内容。 请注意,鉴于可以在类路径中找到一个内存测试数据库,上述解决方案将调出一个内存测试数据库。

    【讨论】:

    • 这是一个集成测试,而不是OP提到的单元测试
    • @IwoKucharski。您对术语是正确的。但是:鉴于 Spring Data 为您实现了接口,您很难使用 Spring,此时它变成了一个集成测试。如果我问这样的问题,我可能还会在不考虑术语的情况下要求进行单元测试。因此,我不认为这是问题的主要,甚至是中心点。
    • @RunWith(SpringRuner.class) 现在已包含在 @DataJpaTest 中。
    • @IwoKucharski,为什么这是集成测试,而不是单元测试?
    • @user1182625 @RunWith(SpringRunner.class 启动 spring 上下文,这意味着它正在检查多个单元之间的集成。单元测试是测试单个单元 -> 单个类。然后你写MyClass sut = new MyClass(); 并测试 sut 对象(sut = 被测服务)
    【解决方案3】:

    这可能来得太晚了,但我为此写了一些东西。我的库将为您模拟基本的 crud 存储库方法,并解释查询方法的大部分功能。 您必须为自己的本机查询注入功能,但其余部分已为您完成。

    看看:

    https://github.com/mmnaseri/spring-data-mock

    更新

    它现在位于 Maven 中心并且状态非常好。

    【讨论】:

      【解决方案4】:

      如果您使用的是 Spring Boot,您可以简单地使用 @SpringBootTest 加载您的 ApplicationContext(这是您的堆栈跟踪对您咆哮的原因)。这允许您在您的 spring-data 存储库中自动装配。请务必添加@RunWith(SpringRunner.class),以便获取特定于弹簧的注释:

      @RunWith(SpringRunner.class)
      @SpringBootTest
      public class OrphanManagementTest {
      
        @Autowired
        private UserRepository userRepository;
      
        @Test
        public void saveTest() {
          User user = new User("Tom");
          userRepository.save(user);
          Assert.assertNotNull(userRepository.findOne("Tom"));
        }
      }
      

      您可以在他们的docs 中阅读有关在 Spring Boot 中进行测试的更多信息。

      【讨论】:

      • 这是一个相当好的例子,但在我看来过于简单。有没有这种测试甚至会失败的情况??
      • 不是这个本身,但假设你想测试Predicates(这是我的用例)它工作得很好。
      • 对我来说存储库始终为空。有什么帮助吗?
      • 这是恕我直言的最佳答案。通过这种方式,您可以测试创建实体表的 CrudRepo、实体和 DDL 脚本。
      • 我写了一个和这个完全一样的测试。当 Repository 的实现使用 jdbcTemplate 时,它​​可以完美地工作。但是,当我更改 spring-data 的实现(通过从 Repository 扩展接口)时,测试失败并且 userRepository.findOne 返回 null。关于如何解决这个问题的任何想法?
      【解决方案5】:

      在spring boot的最新版本2.1.1.RELEASE中,简单如下:

      @RunWith(SpringRunner.class)
      @SpringBootTest(classes = SampleApplication.class)
      public class CustomerRepositoryIntegrationTest {
      
          @Autowired
          CustomerRepository repository;
      
          @Test
          public void myTest() throws Exception {
      
              Customer customer = new Customer();
              customer.setId(100l);
              customer.setFirstName("John");
              customer.setLastName("Wick");
      
              repository.save(customer);
      
              List<?> queryResult = repository.findByLastName("Wick");
      
              assertFalse(queryResult.isEmpty());
              assertNotNull(queryResult.get(0));
          }
      }
      

      完整代码:

      https://github.com/jrichardsz/spring-boot-templates/blob/master/003-hql-database-with-integration-test/src/test/java/test/CustomerRepositoryIntegrationTest.java

      【讨论】:

      • 这是相当不完整的“示例”:无法构建,“集成”测试使用与生产代码相同的配置。 IE。一文不值。
      • 我很抱歉。因为这个错误,我会鞭打我。请再试一次!
      • 这也适用于 Spring Boot 的 2.0.0.RELEASE
      • 你应该在这个测试中使用嵌入式数据库
      【解决方案6】:

      当你真的想为 spring 数据存储库编写 i-test 时,你可以这样做:

      @RunWith(SpringRunner.class)
      @DataJpaTest
      @EnableJpaRepositories(basePackageClasses = WebBookingRepository.class)
      @EntityScan(basePackageClasses = WebBooking.class)
      public class WebBookingRepositoryIntegrationTest {
      
          @Autowired
          private WebBookingRepository repository;
      
          @Test
          public void testSaveAndFindAll() {
              WebBooking webBooking = new WebBooking();
              webBooking.setUuid("some uuid");
              webBooking.setItems(Arrays.asList(new WebBookingItem()));
              repository.save(webBooking);
      
              Iterable<WebBooking> findAll = repository.findAll();
      
              assertThat(findAll).hasSize(1);
              webBooking.setId(1L);
              assertThat(findAll).containsOnly(webBooking);
          }
      }
      

      要遵循这个示例,您必须使用这些依赖项:

      <dependency>
          <groupId>com.h2database</groupId>
          <artifactId>h2</artifactId>
          <version>1.4.197</version>
          <scope>test</scope>
      </dependency>
      <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>4.12</version>
          <scope>test</scope>
      </dependency>
      <dependency>
          <groupId>org.assertj</groupId>
          <artifactId>assertj-core</artifactId>
          <version>3.9.1</version>
          <scope>test</scope>
      </dependency>
      <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-data-jpa</artifactId>
      </dependency>
      <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-test</artifactId>
          <scope>test</scope>
      </dependency>
      

      【讨论】:

        【解决方案7】:

        使用 JUnit5 和 @DataJpaTest 测试看起来像(kotlin 代码):

        @DataJpaTest
        @ExtendWith(value = [SpringExtension::class])
        class ActivityJpaTest {
        
            @Autowired
            lateinit var entityManager: TestEntityManager
        
            @Autowired
            lateinit var myEntityRepository: MyEntityRepository
        
            @Test
            fun shouldSaveEntity() {
                // when
                val savedEntity = myEntityRepository.save(MyEntity(1, "test")
        
                // then 
                Assertions.assertNotNull(entityManager.find(MyEntity::class.java, savedEntity.id))
            }
        }
        

        您可以使用 org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager 包中的 TestEntityManager 来验证实体状态。

        【讨论】:

        • 为实体 bean 生成 Id 总是更好的春天。
        • 对于 Java,第二行是:@ExtendWith(value = SpringExtension.class)
        • 这给了我一个错误,java.lang.IllegalStateException: Unable to find a @SpringBootConfiguration, you need to use @ContextConfiguration or @SpringBootTest(classes=...) with your test
        【解决方案8】:

        我通过这种方式解决了这个问题 -

            @RunWith(SpringRunner.class)
            @EnableJpaRepositories(basePackages={"com.path.repositories"})
            @EntityScan(basePackages={"com.model"})
            @TestPropertySource("classpath:application.properties")
            @ContextConfiguration(classes = {ApiTestConfig.class,SaveActionsServiceImpl.class})
            public class SaveCriticalProcedureTest {
        
                @Autowired
                private SaveActionsService saveActionsService;
                .......
                .......
        }
        

        【讨论】:

          【解决方案9】:
          springboot 2.4.5
          
          
          import javax.persistence.EntityManager;
          import javax.persistence.ParameterMode;
          import javax.persistence.PersistenceContext;
          import javax.persistence.StoredProcedureQuery;
          
          @Repository
          public class MyRepositoryImpl implements MyRepository {
              @Autowired
              @PersistenceContext(unitName = "MY_JPA_UNIT")
              private EntityManager entityManager;
              
              
              @Transactional("MY_TRANSACTION_MANAGER")
              @Override
              public MyEntity getSomething(Long id) {
              
                  StoredProcedureQuery query = entityManager.createStoredProcedureQuery(
                          "MyStoredProcedure", MyEntity.class);
                  query.registerStoredProcedureParameter("id", Long.class, ParameterMode.IN);
                  query.setParameter("id", id);
          
                  query.execute();
                  
                  @SuppressWarnings("unchecked")
                  MyEntity myEntity = (MyEntity) query.getResultList().stream().findFirst().orElse(null);
                  return myEntity;
              }
          }
          
          import org.junit.jupiter.api.*;
          import org.junit.runner.RunWith;
          import org.mockito.InjectMocks;
          import org.mockito.Mock;
          import org.mockito.Mockito;
          import org.mockito.MockitoAnnotations;
          import org.mockito.junit.MockitoJUnitRunner;
          
          import javax.persistence.EntityManager;
          import javax.persistence.StoredProcedureQuery;
          import java.util.List;
          
          import static org.hamcrest.MatcherAssert.assertThat;
          import static org.hamcrest.Matchers.*;
          
          @RunWith(MockitoJUnitRunner.Silent.class)
          @TestInstance(TestInstance.Lifecycle.PER_CLASS)
          public class MyRepositoryTest {
          
              @InjectMocks
              MyRepositoryImpl myRepository;
          
              @Mock
              private EntityManager entityManager;
          
              @Mock
              private StoredProcedureQuery storedProcedureQuery;
              
              @BeforeAll
              public void init() {
                  MockitoAnnotations.openMocks(this);
                  Mockito.when(entityManager.createStoredProcedureQuery(Mockito.any(), Mockito.any(Class.class)))
                          .thenReturn(storedProcedureQuery);
              }
          
              @AfterAll
              public void tearDown() {
                  // something
              }
              
              @Test
              void testMethod() throws Exception {
                  Mockito.when(storedProcedureQuery.getResultList()).thenReturn(List.of(myEntityMock));
          
                  MyEntity resultMyEntityList = myRepository.getSomething(1l);
          
                  assertThat(resultMyEntityList,
                          allOf(hasProperty("id", org.hamcrest.Matchers.is("1"))
                          . . .
                  );
              }
          }
          

          【讨论】:

            【解决方案10】:

            在 2021 年有了一个新的初始化 springboot 2.5.1 项目,我正在这样做:

            ...
            import org.junit.jupiter.api.Test;
            import org.junit.jupiter.api.extension.ExtendWith;
            import org.mockito.junit.jupiter.MockitoExtension;
            import org.springframework.beans.factory.annotation.Autowired;
            import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
            
            
            @ExtendWith(MockitoExtension.class)
            @DataJpaTest
            public class SomeTest {
            
                @Autowired
                MyRepository repo;
            
                @Test
                public void myTest() throws Exception {
                    repo.save(new MyRepoEntity());
                    /*...
                    / Actual Test. For Example: Will my queries work? ... etc.
                    / ...
                    */
                }
            }
            

            【讨论】:

            • 我认为这是无用的测试。您正在测试 JPA 而不是您的代码。 JPA 已经过测试,应该假设是这样。也许我会创建一个单独的测试来检查字段的映射或检查注释中列的值,以检测列值名称的变化。如果您自己启动内存数据库实例并加载表创建脚本
            • 我认为您的评论指向了正确的方向。上面的代码旨在作为 springboot 2.5.1 应用程序上下文的起点。实际的测试代码不是示例的一部分。这个例子只是关于配置。
            【解决方案11】:

            您可以使用仅关注JPA 组件@DataJpaTest 注释。默认情况下,它会扫描 @Entity 类并配置带有 @Repository 注释的 Spring Data JPA 存储库。

            默认情况下,使用@DataJpaTest 注释的测试在每个测试结束时为transactional and roll back

            //in junit 5
            @RunWith(SpringRunner.class)
            @DataJpaTest
            public class EmployeeRepoTest {
            
            @Autowired
            EmployeeRepo repository;
             
            @Test
            public void testRepository() 
            {
                EmployeeEntity employee = new EmployeeEntity();
                employee.setFirstName("Anand");
                employee.setProject("Max Account");
                 
                repository.save(employee);
                 
                Assert.assertNotNull(employee.getId());
              }
            }
            

            Junit 4 语法将与 SpringRunner 类一起使用。

            //Junit 4
            @RunWith(SpringRunner.class)
            @DataJpaTest
            public class DataRepositoryTest{
            //
            }
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2019-01-23
              • 1970-01-01
              • 1970-01-01
              • 2014-08-04
              • 2019-03-22
              • 2021-09-17
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多