DataJpaTest 无法在单元测试中更新

Posted

技术标签:

【中文标题】DataJpaTest 无法在单元测试中更新【英文标题】:DataJpaTest fail to update in unit test 【发布时间】:2018-01-18 21:35:12 【问题描述】:

我试图找出为什么我的单元测试不起作用。我看到 Hibernate 在更新之前进行了插入。 为什么这样做? 是测试失败的原因吗?

我已经为测试环境设置了hsqldb,该服务在mysql中似乎可以正常工作。

@Repository
public interface UserDataRepository extends CrudRepository<UserData, Integer> 

    @Transactional
    @Modifying
    @Query("UPDATE UserData ud SET chips = chips + :delta  WHERE ud.id = :userId")
    void addChipsToUser(@Param("userId") int userId, @Param("delta") long delta);

我的测试课:

@RunWith(SpringRunner.class)
@DataJpaTest
public class TestJPASlice 

    @Autowired
    private TestEntityManager entityManager;

    @Autowired
    private UserDataRepository repository;

    @Test
    public void testAddChipsToUser() 
            UserData data = new UserData();
            data.setChips(100);
            data.setId(13);                
            this.entityManager.persist(data);                

            System.err.println("pre u");                
            this.repository.addChipsToUser(13, 500);                
            System.err.println("post u");

            UserData two = this.repository.findOne(13);
            assertThat(two.getId()).isEqualTo(13);
            assertThat(two.getChips()).isEqualTo(600);
    

这是我得到的输出:

Hibernate: update user_player_data set chips=chips+? where user_id=?
2017-08-10 11:33:37.794  WARN 2128 --- [main] o.h.engine.jdbc.spi.SqlExceptionHelper   : SQL Warning Code: -1100, SQLState: 02000
2017-08-10 11:33:37.795  WARN 2128 --- [main] o.h.engine.jdbc.spi.SqlExceptionHelper   : no hay datos
2017-08-10 11:33:37.796  INFO 2128 --- [main] o.s.t.c.transaction.TransactionContext   : Rolled back transaction for test context [DefaultTestContext@29626d54... 
2017-08-10 11:33:37.801  INFO 2128 --- [main] o.s.t.c.transaction.TransactionContext   : Began transaction (1) for test context [DefaultTestContext@29626d54... 
pre u
Hibernate: insert into user_player_data (chips, user_id) values (?, ?)
Hibernate: update user_player_data set chips=chips+? where user_id=?
post u
2017-08-10 11:33:37.874  INFO 2128 --- [main] o.s.t.c.transaction.TransactionContext   : Rolled back transaction for test context [DefaultTestContext@29626d54... 
Tests run: 2, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 3.073 sec <<< FAILURE! - in service.chipBank.TestJPASlice
testAddChipsToUser(service.chipBank.TestJPASlice)  Time elapsed: 0.074 sec  <<< FAILURE!
org.junit.ComparisonFailure: expected:<[6]00L> but was:<[1]00L>
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at service.chipBank.TestJPASlice.testAddChipsToUser(TestJPASlice.java:43)

【问题讨论】:

【参考方案1】:

为此,您只需启用 clearAutomatically 标志:

@Modifying(clearAutomatically = true)

为了在执行修改查询后清除底层持久性上下文。

然后您可以在日志中看到后续的选择查询:

2017-08-10 22:20:09.693 DEBUG 1948 --- [           main] org.hibernate.SQL                        : insert into user_player_data (chips, user_id) values (?, ?)
Hibernate: insert into user_player_data (chips, user_id) values (?, ?)
2017-08-10 22:20:09.695 TRACE 1948 --- [           main] o.h.type.descriptor.sql.BasicBinder      : binding parameter [1] as [BIGINT] - [100]
2017-08-10 22:20:09.696 TRACE 1948 --- [           main] o.h.type.descriptor.sql.BasicBinder      : binding parameter [2] as [INTEGER] - [13]
2017-08-10 22:20:09.700 DEBUG 1948 --- [           main] org.hibernate.SQL                        : update user_player_data set chips=chips+? where user_id=?
Hibernate: update user_player_data set chips=chips+? where user_id=?
2017-08-10 22:20:09.700 TRACE 1948 --- [           main] o.h.type.descriptor.sql.BasicBinder      : binding parameter [1] as [BIGINT] - [500]
2017-08-10 22:20:09.701 TRACE 1948 --- [           main] o.h.type.descriptor.sql.BasicBinder      : binding parameter [2] as [INTEGER] - [13]
post u
2017-08-10 22:20:09.708 DEBUG 1948 --- [           main] org.hibernate.SQL                        : select userdata0_.user_id as user_id1_0_0_, userdata0_.chips as chips2_0_0_ from user_player_data userdata0_ where userdata0_.user_id=?
Hibernate: select userdata0_.user_id as user_id1_0_0_, userdata0_.chips as chips2_0_0_ from user_player_data userdata0_ where userdata0_.user_id=?
2017-08-10 22:20:09.708 TRACE 1948 --- [           main] o.h.type.descriptor.sql.BasicBinder      : binding parameter [1] as [INTEGER] - [13]
2017-08-10 22:20:09.712 TRACE 1948 --- [           main] o.h.type.descriptor.sql.BasicExtractor   : extracted value ([chips2_0_0_] : [BIGINT]) - [600]
2017-08-10 22:20:09.751  INFO 1948 --- [           main] o.s.t.c.transaction.TransactionContext   : Rolled back transaction for test context [DefaultTestContext@ca263c2 testClass = TestJPASlice, testInstance = com.example.demo.TestJPASlice@2145433b, testMethod = testAddChipsToUser@TestJPASlice, testException = [null], mergedContextConfiguration = [MergedContextConfiguration@589b3632 testClass = TestJPASlice, locations = '', classes = 'class com.example.demo.DemoApplication', contextInitializerClasses = '[]', activeProfiles = '', propertySourceLocations = '', propertySourceProperties = 'org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true', contextCustomizers = set[[ImportsContextCustomizer@45f45fa1 key = [org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration, org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration, org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration, org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration, org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration, org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration, org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration, org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration, org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration, org.springframework.boot.test.autoconfigure.jdbc.TestDatabaseAutoConfiguration, org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManagerAutoConfiguration]], org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@7a765367, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@3043fe0e, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.autoconfigure.OverrideAutoConfigurationContextCustomizerFactory$DisableAutoConfigurationContextCustomizer@c46bcd4, org.springframework.boot.test.autoconfigure.filter.TypeExcludeFiltersContextCustomizer@351584c0, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@ee27f40e, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer@cb51256], contextLoader = 'org.springframework.boot.test.context.SpringBootContextLoader', parent = [null]]].
2017-08-10 22:20:09.753  INFO 1948 --- [       Thread-2] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@4944252c: startup date [Thu Aug 10 22:20:07 BST 2017]; root of context hierarchy
2017-08-10 22:20:09.754  INFO 1948 --- [       Thread-2] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
2017-08-10 22:20:09.754  INFO 1948 --- [       Thread-2] org.hibernate.tool.hbm2ddl.SchemaExport  : HHH000227: Running hbm2ddl schema export
2017-08-10 22:20:09.755 DEBUG 1948 --- [       Thread-2] org.hibernate.SQL                        : drop table user_player_data if exists
Hibernate: drop table user_player_data if exists

有关标志take a look at the Spring Data JPA Documentation的更多信息。

【讨论】:

@dimitrisli 也许你知道还有其他选择吗?因为添加 clearAutomatically 不适合我。 @OrestKyrylchuk 显然很难在没有任何细节的情况下推测您的情况。请在一个独立的问题上制定您的用例。

以上是关于DataJpaTest 无法在单元测试中更新的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot DataJpaTest 单元测试恢复到 H2 而不是 mySql

如果 Spring 安全性在类路径上,则无法使用 @DataJpaTest

IDEA单元测 试控制台不能输入数据 解决方案

单元测试集成测试

单元测试基本框架和8个测试方面

单元测试基本框架和8个测试方面