我想写一些测试,通过一些给定的属性找到一个对象;但在此之前,我想使用setUp方法初始化我想测试的对象。但此对象还依赖于另一个我想创建为模拟的对象,但我无法调用test methid方法,因为它会抛出此异常:数据访问权限无效应用程序使用异常:组织。休眠。瞬时属性值异常:对象引用了一个未保存的临时示例-刷新前保存临时示例。这是下面的示例代码,请告诉我缺少了什么以及如何使它更好,谢谢。
@DataJpaTest(properties = {
"spring.jpa.properties.javax.persistence.validation.mode=none"
})
@ExtendWith(MockitoExtension.class)
public class EmailVerificationTokenRepositoryTest {
@Autowired
private EmailVerificationTokenRepository repository;
@Mock
private UserRepository userRepository;
/**
* Test of findByToken method, of class EmailVerificationTokenRepository.
*/
@BeforeEach
public void setUp() {
Set role = new HashSet<>();
role.add("ROLE_USER");
Users expected = Users.builder()
.id(null)
.email("david@gmail.com")
.password("1234")
.isEnabled(true)
.isNonLocked(true)
.roles(role)
.createdAt(LocalDateTime.now())
.build();
Mockito.when(userRepository.save(expected)).thenReturn(expected);
Users actual = userRepository.save(expected);
System.out.println(actual);
EmailVerificationToken evt = EmailVerificationToken.builder()
.createdAt(LocalDateTime.now())
.expiresAt(LocalDateTime.now().plusHours(4))
.token("token")
.user(actual)
.build();
repository.save(evt);
}
@AfterEach
public void tearDown() {
repository.deleteAll();
}
@Test
@DisplayName("Test to find Email Verification Object By Token")
public void testFindByToken() {
String token = "token";
Optional<EmailVerificationToken> result = repository.findByToken(token);
assertTrue(result.isPresent());
}
/**
* Test of findByUser method, of class EmailVerificationTokenRepository.
*/
@Test
@Disabled
@DisplayName("Test to find Email Verification Object By User")
public void testFindByUser() {
//Given
Set role = new HashSet<>();
role.add("ROLE_USER");
Users user = Users.builder()
.id(null)
.email("david@gmail.com")
.password("1234")
.isEnabled(true)
.isNonLocked(true)
.roles(role)
.createdAt(LocalDateTime.now())
.build();
Optional<EmailVerificationToken> result = repository.findByUser(user);
assertTrue(result.isPresent());
}
}
这些是我的日志:
2023-02-26 18:57:11.507 INFO [,,] 12780 --- [ main] u.r.EmailVerificationTokenRepositoryTest : Started EmailVerificationTokenRepositoryTest in 7.485 seconds (JVM running for 11.929)
2023-02-26 18:57:11.588 INFO [,,] 12780 --- [ main] o.s.t.c.transaction.TransactionContext : Began transaction (1) for test context [DefaultTestContext@2b76ff4e testClass = EmailVerificationTokenRepositoryTest, testInstance = com.slinkdigital.user.repository.EmailVerificationTokenRepositoryTest@73eae5f, testMethod = testFindByToken@EmailVerificationTokenRepositoryTest, testException = [null], mergedContextConfiguration = [MergedContextConfiguration@7a1234bf testClass = EmailVerificationTokenRepositoryTest, locations = '{}', classes = '{class com.slinkdigital.user.UserApplication}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{spring.jpa.properties.javax.persistence.validation.mode=none, org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTestContextBootstrapper=true}', contextCustomizers = set[[ImportsContextCustomizer@2f62ea70 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.sql.init.SqlInitializationAutoConfiguration, 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@6f3187b0, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@189cbd7c, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.autoconfigure.OverrideAutoConfigurationContextCustomizerFactory$DisableAutoConfigurationContextCustomizer@723e88f9, org.springframework.boot.test.autoconfigure.actuate.metrics.MetricsExportContextCustomizerFactory$DisableMetricExportContextCustomizer@6ea2bc93, org.springframework.boot.test.autoconfigure.filter.TypeExcludeFiltersContextCustomizer@351584c0, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@474abc3a, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer@48c76607, org.springframework.boot.test.context.SpringBootTestArgs@1, org.springframework.boot.test.context.SpringBootTestWebEnvironment@0], contextLoader = 'org.springframework.boot.test.context.SpringBootContextLoader', parent = [null]], attributes = map['org.springframework.test.context.event.ApplicationEventsTestExecutionListener.recordApplicationEvents' -> false, 'org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener.mocks' -> org.mockito.internal.configuration.InjectingAnnotationEngine$$Lambda$406/0x0000000800e49720@4902c584]]; transaction manager [org.springframework.orm.jpa.JpaTransactionManager@42ef5216]; rollback [true]
Users(id=null, email=david@gmail.com, password=1234, createdAt=2023-02-26T18:57:11.641991300, isNonLocked=false, isEnabled=false, roles=[ROLE_USER])
2023-02-26 18:57:11.774 DEBUG [,,] 12780 --- [ main] org.hibernate.SQL :
insert
into
email_verification_token
(id, created_at, expires_at, token, user_id)
values
(default, ?, ?, ?, ?)
Hibernate:
insert
into
email_verification_token
(id, created_at, expires_at, token, user_id)
values
(default, ?, ?, ?, ?)
2023-02-26 18:57:12.033 INFO [,,] 12780 --- [ main] o.s.t.c.transaction.TransactionContext : Rolled back transaction for test: [DefaultTestContext@2b76ff4e testClass = EmailVerificationTokenRepositoryTest, testInstance = com.slinkdigital.user.repository.EmailVerificationTokenRepositoryTest@73eae5f, testMethod = testFindByToken@EmailVerificationTokenRepositoryTest, testException = org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing : com.slinkdigital.user.domain.EmailVerificationToken.user -> com.slinkdigital.user.domain.Users; nested exception is java.lang.IllegalStateException: org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing : com.slinkdigital.user.domain.EmailVerificationToken.user -> com.slinkdigital.user.domain.Users, mergedContextConfiguration = [MergedContextConfiguration@7a1234bf testClass = EmailVerificationTokenRepositoryTest, locations = '{}', classes = '{class com.slinkdigital.user.UserApplication}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{spring.jpa.properties.javax.persistence.validation.mode=none, org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTestContextBootstrapper=true}', contextCustomizers = set[[ImportsContextCustomizer@2f62ea70 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.sql.init.SqlInitializationAutoConfiguration, 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@6f3187b0, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@189cbd7c, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.autoconfigure.OverrideAutoConfigurationContextCustomizerFactory$DisableAutoConfigurationContextCustomizer@723e88f9, org.springframework.boot.test.autoconfigure.actuate.metrics.MetricsExportContextCustomizerFactory$DisableMetricExportContextCustomizer@6ea2bc93, org.springframework.boot.test.autoconfigure.filter.TypeExcludeFiltersContextCustomizer@351584c0, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@474abc3a, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer@48c76607, org.springframework.boot.test.context.SpringBootTestArgs@1, org.springframework.boot.test.context.SpringBootTestWebEnvironment@0], contextLoader = 'org.springframework.boot.test.context.SpringBootContextLoader', parent = [null]], attributes = map['org.springframework.test.context.event.ApplicationEventsTestExecutionListener.recordApplicationEvents' -> false, 'org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener.mocks' -> org.mockito.internal.configuration.InjectingAnnotationEngine$$Lambda$406/0x0000000800e49720@4902c584]]
Tests run: 2, Failures: 0, Errors: 1, Skipped: 1, Time elapsed: 10.605 s <<< FAILURE! - in com.slinkdigital.user.repository.EmailVerificationTokenRepositoryTest
testFindByToken Time elapsed: 0.024 s <<< ERROR!
org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing : com.slinkdigital.user.domain.EmailVerificationToken.user -> com.slinkdigital.user.domain.Users; nested exception is java.lang.IllegalStateException: org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing : com.slinkdigital.user.domain.EmailVerificationToken.user -> com.slinkdigital.user.domain.Users
at com.slinkdigital.user.repository.EmailVerificationTokenRepositoryTest.testFindByToken(EmailVerificationTokenRepositoryTest.java:76)
Caused by: java.lang.IllegalStateException: org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing : com.slinkdigital.user.domain.EmailVerificationToken.user -> com.slinkdigital.user.domain.Users
at com.slinkdigital.user.repository.EmailVerificationTokenRepositoryTest.testFindByToken(EmailVerificationTokenRepositoryTest.java:76)
Caused by: org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing : com.slinkdigital.user.domain.EmailVerificationToken.user -> com.slinkdigital.user.domain.Users
at com.slinkdigital.user.repository.EmailVerificationTokenRepositoryTest.testFindByToken(EmailVerificationTokenRepositoryTest.java:76)
我将感激每一个帮助我可以得到,谢谢。
1条答案
按热度按时间3mpgtkmj1#
导致原因:org. hib.临时属性值异常:对象引用未保存的 transient 示例-刷新前保存 transient 示例:* * com. slink数字.用户.域.电子邮件验证令牌.用户-〉com. slink数字.用户.域.用户
错误消息已经给了你一些提示。这是因为你创建的
EmailVerificationToken
的用户不是由JPA管理的。因为你使用了一个mocked的UserRepository
来创建它。所以从JPA的Angular 来看,这个用户示例从来就不存在。您必须使用实际**
UserRepository
创建用户或获取现有用户,而不是使用模拟。没有其他选择。为什么要使用模拟UserRepository
而不是实际UserRepository
?因此,更改为以下内容应该可以解决该问题: