如何使用JOOQ测试事务方法



我正在尝试进行一些测试,看看我的事务方法是否正常工作。然而,我不完全理解我是否应该模拟数据库,以及JOOQ是如何进入这个等式的。下面是带有向数据库中添加角色事务的Service类。

@Service
public class RoleService implements GenericRepository<Role>
{
@Autowired
private DSLContext roleDSLContext;

@Override
@Transactional
public int add(Role roleEntry)
{
return roleDSLContext.insertInto(Tables.ROLE,
Tables.ROLE.NAME,
Tables.ROLE.DESCRIPTION,
Tables.ROLE.START_DATE,
Tables.ROLE.END_DATE,
Tables.ROLE.ID_RISK,
Tables.ROLE.ID_TYPE,
Tables.ROLE.ID_CONTAINER)
.values(roleEntry.getName(),
roleEntry.getDescription(),
roleEntry.getStartDate(),
roleEntry.getEndDate(),
roleEntry.getIdRisk(),
roleEntry.getIdType(),
roleEntry.getIdContainer())
.execute();
}
}

我使用MySQL,与数据库的连接是使用spring配置文件进行的

spring.datasource.url=jdbc:mysql://localhost:3306/role_managementverifyServerCertificate=false&useSSL=true
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

我假设我不必每次测试事务并在事务完成后关闭连接时都重新连接到数据库。我知道有

MockDataProvider provider = new MockDataProvider()

但我不明白它是怎么工作的。

测试上述方法的最佳方法是什么?

免责声明

你读过jOOQ手册中关于嘲笑数据库的大免责声明吗?

免责声明:用这个jOOQ API模拟JDBC连接的一般想法是使用一个非常简单的JDBC抽象提供快速的解决方法、注入点等。不建议使用此模拟API模拟整个数据库(包括复杂的状态转换、事务、锁定等(。一旦有了这个需求,请考虑使用实际的数据库产品进行集成测试,而不是在MockDataProvider中实现测试数据库。

非常建议您使用类似testcontainers的东西来集成测试您的应用程序,而不是实现自己的"数据库产品";通过jOOQ的模拟SPI(或任何其他模拟方式(。

如果你必须嘲笑

要回答您的实际问题,您可以通过编程配置DSLContext,例如使用:

@Bean
public DSLContext getDSLContext() {
if (testing)
return // the mocking context
else
return // the actual context
}

现在,将一些Spring概要文件值或其他任何值注入到上面包含DSLContextbean配置的配置类中,就可以完成所有操作了。

或者,使用构造函数注入而不是字段注入(这有很多好处(

@Service
public class RoleService implements GenericRepository<Role> {
final DSLContext ctx;
public RoleService(DSLContext ctx) {
this.ctx = ctx;
}
// ...
}

因此,您可以在模拟数据库的测试中手动构建服务:

RoleService testService = new RoleService(mockingContext);
testService.add(...);

但正如你所看到的,嘲笑是完全无用的。因为您想要测试的是数据库中存在副作用(插入了一条记录(,为了测试该副作用,您需要再次查询数据库,但除非您也模拟它,或者重新实现整个RDBMS,否则您将不会在数据库中看到该记录。那么,为什么不只是集成测试您的代码呢?

最新更新