欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 维修 > 2.4 测试数据与初始化

2.4 测试数据与初始化

2025/2/13 8:42:00 来源:https://blog.csdn.net/weixin_43476824/article/details/145600808  浏览:    关键词:2.4 测试数据与初始化

测试数据与初始化

在 Spring Test 中,合理管理测试数据的初始化和清理是保证测试可靠性的关键。本章将介绍多种数据准备方式,涵盖 SQL 脚本执行编程式初始化动态数据生成,并提供最佳实践示例。


1. 使用 @Sql 执行 SQL 脚本

作用

  • 在测试方法前后执行 SQL 脚本:快速初始化或清理数据库。
  • 支持事务内/外执行(默认在事务内)。

核心属性

属性作用
scripts指定 SQL 脚本路径
executionPhase执行阶段(BEFORE_TEST_METHOD / AFTER_TEST_METHOD)
config自定义脚本配置(如注释分隔符)

示例代码

@ExtendWith(SpringExtension.class)  
@ContextConfiguration(classes = DataSourceConfig.class)  
@Transactional  
public class SqlAnnotationTest {  @Autowired  private JdbcTemplate jdbcTemplate;  // 测试前执行初始化脚本  @Test  @Sql(scripts = "classpath:init-data.sql")  void testWithInitialData() {  Integer count = jdbcTemplate.queryForObject("SELECT COUNT(*) FROM users", Integer.class);  assertEquals(2, count); // init-data.sql 插入了 2 条记录  }  // 测试后执行清理脚本  @Test  @Sql(  scripts = "classpath:cleanup-data.sql",  executionPhase = Sql.ExecutionPhase.AFTER_TEST_METHOD  )  void testWithCleanup() {  jdbcTemplate.update("INSERT INTO users (name) VALUES ('Alice')");  }  
}  

init-data.sql 内容

INSERT INTO users (id, name) VALUES (1, 'TestUser1');  
INSERT INTO users (id, name) VALUES (2, 'TestUser2');  

cleanup-data.sql 内容

DELETE FROM users WHERE name = 'Alice';  

2. 编程式数据初始化

使用 JdbcTemplate 动态操作数据

适用于需要灵活生成数据的场景(如随机值、循环插入)。

示例代码

@ExtendWith(SpringExtension.class)  
@ContextConfiguration(classes = DataSourceConfig.class)  
@Transactional  
public class ProgrammaticDataTest {  @Autowired  private JdbcTemplate jdbcTemplate;  @BeforeEach  void setupData() {  // 在每个测试前插入基础数据  jdbcTemplate.update("INSERT INTO users (name) VALUES ('BaseUser')");  }  @Test  void testDynamicData() {  // 动态插入测试数据  jdbcTemplate.update("INSERT INTO users (name) VALUES (?)", "DynamicUser");  Integer count = jdbcTemplate.queryForObject("SELECT COUNT(*) FROM users", Integer.class);  assertEquals(2, count); // BaseUser + DynamicUser  }  @AfterEach  void cleanupData() {  // 清理数据(通常由事务回滚处理,此处仅为示例)  jdbcTemplate.update("DELETE FROM users WHERE name IN ('BaseUser', 'DynamicUser')");  }  
}  

3. 参数化测试与动态数据

结合 JUnit 5 的 @ParameterizedTest 实现数据驱动测试。

示例代码

@ExtendWith(SpringExtension.class)  
@ContextConfiguration(classes = DataSourceConfig.class)  
@Transactional  
public class ParameterizedDataTest {  @Autowired  private UserRepository userRepository;  // 定义参数化数据源  @ParameterizedTest  @ValueSource(strings = {"Alice", "Bob", "Charlie"})  void testCreateUsers(String name) {  User user = new User(name);  userRepository.save(user);  assertNotNull(user.getId());  }  // 使用 CSV 数据源  @ParameterizedTest  @CsvSource({"1, Alice", "2, Bob"})  void testFindUser(Long id, String expectedName) {  User user = userRepository.findById(id).orElseThrow();  assertEquals(expectedName, user.getName());  }  
}  

4. 事务回滚自动清理数据

利用 @Transactional 的默认回滚机制,无需手动清理。

示例场景

@ExtendWith(SpringExtension.class)  
@ContextConfiguration(classes = DataSourceConfig.class)  
@Transactional // 类级别启用事务  
public class TransactionalCleanupTest {  @Autowired  private UserService userService;  @Test  void testUserCreation() {  userService.createUser("Alice");  // 事务回滚后,Alice 不会持久化到数据库  }  @Test  @Commit  void testPersistentUser() {  userService.createUser("Bob");  // 提交事务,Bob 会持久化到数据库  }  
}  

5. 自定义数据初始化工具

场景需求

在多测试类中复用数据初始化逻辑,减少重复代码。

实现步骤

步骤 1:创建数据工具类

public class TestDataUtils {  public static void insertUser(JdbcTemplate jdbcTemplate, String name) {  jdbcTemplate.update("INSERT INTO users (name) VALUES (?)", name);  }  public static void clearUsers(JdbcTemplate jdbcTemplate) {  jdbcTemplate.update("DELETE FROM users");  }  
}  

步骤 2:在测试类中使用工具类

@ExtendWith(SpringExtension.class)  
@ContextConfiguration(classes = DataSourceConfig.class)  
@Transactional  
public class DataUtilTest {  @Autowired  private JdbcTemplate jdbcTemplate;  @BeforeEach  void setup() {  TestDataUtils.insertUser(jdbcTemplate, "ToolUser");  }  @Test  void testDataUtil() {  Integer count = jdbcTemplate.queryForObject("SELECT COUNT(*) FROM users", Integer.class);  assertEquals(1, count);  }  
}  

6. 最佳实践总结

场景推荐方式优点
固定数据初始化@Sql 注解加载 SQL 脚本维护简单,数据与代码分离
动态数据生成编程式操作(JdbcTemplate灵活性高,支持复杂逻辑
多测试数据复用自定义工具类减少代码冗余,提升可维护性
参数化测试JUnit 5 @ParameterizedTest数据驱动,覆盖多种边界条件

注意事项

  • 避免在测试中依赖外部数据库的持久化数据。
  • 始终优先使用事务回滚确保测试隔离性。
  • 对于复杂数据场景,可结合 @Sql 和编程式初始化。

通过合理选择数据初始化策略,可以显著提升测试代码的可读性和可维护性。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com