我按照一篇关于 JUnit 测试的文章为我的用户模型编写了一个 JUnit 测试:
import dev.cv.taskmasterserver.entity.User;
import dev.cv.taskmasterserver.repository.UserRepository;
import org.junit.jupiter.api.AfterEach;import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
@DataJpaTest
public class UserServiceImplAnotherTest {
@Autowiredprivate UserRepository userRepository;
private User testUser;
@BeforeEach
public void setUp() {
// Initialize test data before each test method
testUser = new User()
.setUsername("johnDoe123")
.setFirstName("John")
.setLastName("Doe")
.setPassword("f823hfas");
userRepository.save(testUser);
}
@AfterEach
public void tearDown() {
// Release test data after each test method
userRepository.delete(testUser);
}
@Test
public void givenUser_whenSaved_thenCanBeFoundById() {
User savedUser = userRepository.findById(testUser.getId()).orElse(null);
assertNotNull(savedUser);
assertEquals(testUser.getUsername(), savedUser.getUsername());
assertEquals(testUser.getPassword(), savedUser.getPassword());
}
}
当我运行测试时,出现以下错误:
java.lang.IllegalStateException: Failed to load ApplicationContext for [MergedContextConfiguration@25aeb5ac testClass = dev.francisbernas.taskmasterserver.service.UserServiceImplAnotherTest, locations = [], classes = [dev.francisbernas.taskmasterserver.TaskMasterServerApplication], contextInitializerClasses = [], activeProfiles = [], propertySourceDescriptors = [], propertySourceProperties = ["org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTestContextBootstrapper=true"], contextCustomizers = [[ImportsContextCustomizer@c755b2 key = [org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration, org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration, org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManagerAutoConfiguration, org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration, org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration, org.springframework.boot.autoconfigure.sql.init.SqlInitializationAutoConfiguration, org.springframework.boot.test.autoconfigure.jdbc.TestDatabaseAutoConfiguration, org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration, org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration, org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration, org.springframework.boot.autoconfigure.jdbc.JdbcClientAutoConfiguration, org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration, org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration]], org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@23941fb4, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@5d908d47, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.autoconfigure.OverrideAutoConfigurationContextCustomizerFactory$DisableAutoConfigurationContextCustomizer@7d322cad, org.springframework.boot.test.autoconfigure.actuate.observability.ObservabilityContextCustomizerFactory$DisableObservabilityContextCustomizer@1f, org.springframework.boot.test.autoconfigure.filter.TypeExcludeFiltersContextCustomizer@34be3d80, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@f0395ca5, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizer@4b86805d, org.springframework.boot.test.context.SpringBootTestAnnotation@5be093d3], contextLoader = org.springframework.boot.test.context.SpringBootContextLoader, parent = null]
我尝试添加注释@SpringBootTest,但它导致了不同的错误:
java.lang.IllegalStateException: Configuration error: found multiple declarations of @BootstrapWith for test class [dev.francisbernas.taskmasterserver.service.UserServiceImplAnotherTest]: [@org.springframework.test.context.BootstrapWith(value=org.springframework.boot.test.context.SpringBootTestContextBootstrapper.class), @org.springframework.test.context.BootstrapWith(value=org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTestContextBootstrapper.class)]
@Autowired
和 private
之间添加空格来确保代码格式正确: @Autowired
private UserRepository userRepository;
@DataJpaTest
注释的测试是事务性的,并在每次测试结束时回滚,利用嵌入式内存数据库。如果遇到异常,请考虑指定内存数据库,例如application.yml
中的H2。或者,为了更好地处理测试,请使用 @ActiveProfiles(value = "test")
。使用单独的数据库进行测试时,将
@ActiveProfiles(value = "test")
应用于测试类,该测试类将从 src/main/resources/application-test.yml
加载数据库配置。确保创建此文件并将测试数据库配置添加为普通 Spring 数据源配置。
示例
application-test.yml
内容:
spring:
datasource:
url: jdbc:mysql://localhost:3306/bookdb
username: USERNAME
password: PASSWORD
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
。精炼代码示例:
@DataJpaTest
@ActiveProfiles(value = "test")
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
public class UserServiceImplAnotherTest {
@Autowired
private UserRepository userRepository;
private User testUser;
@BeforeEach
public void setUp() {
testUser = new User()
.setUsername("johnDoe123")
.setFirstName("John")
.setLastName("Doe")
.setPassword("f823hfas");
userRepository.save(testUser);
}
@AfterEach
public void tearDown() {
userRepository.delete(testUser);
}
@Test
public void givenUser_whenSaved_thenCanBeFoundById() {
User savedUser = userRepository.findById(testUser.getId()).orElse(null);
assertNotNull(savedUser);
assertEquals(testUser.getUsername(), savedUser.getUsername());
assertEquals(testUser.getPassword(), savedUser.getPassword());
}
}
有关
@DataJpaTest
的更多信息,请参阅 Spring Boot 文档。