在 Spring 中使用 DBUnit,而无需通过 "nativequery" 定义实体



我试图在测试Spring控制器时使用DBunit。测试初始化失败,因为我的数据集包含不是由实体定义的表/列。

查询是用nativeQuery = true标志定义的,所以我不希望事情出错:

@Query(value = "select * from TEST_TABLE where TEST_COLUMN = '2'";, nativeQuery = true)
TestClass getTestClass();

Dataset.xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<dataset>
<TEST_TABLE TEST_COLUMN="2"/>
</dataset>

测试类:

@RunWith(SpringJUnit4ClassRunner.class)
@ActiveProfiles("test")
@ContextConfiguration(classes = {Application.class, RepoTestApplication.class})
@SpringBootTest(classes = MockServletContext.class)
@TestPropertySource(properties = {"server.port=8444","hibernate.hbm2ddl.auto=create-drop"})
@WebAppConfiguration
@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_CLASS)
@TestExecutionListeners({DbUnitTestExecutionListener.class, DependencyInjectionTestExecutionListener.class,
DirtiesContextBeforeModesTestExecutionListener.class})
@DatabaseSetup("classpath:datasets/Dataset.xml")
public class TestClassTest { ... }

引用的"RepoTestApplication.class":

@Configuration
@EnableJpaRepositories
public class RepoTestApplication {

@Bean
public DataSource dataSource() {
SimpleDriverDataSource dataSource = new SimpleDriverDataSource();
dataSource.setDriverClass(org.h2.Driver.class);
dataSource.setUrl("jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE");
dataSource.setUsername("sa");
return dataSource;
}
}

错误:

org.dbunit.dataset.NoSuchTableException: APP_VER
at org.dbunit.database.DatabaseDataSet.getTableMetaData(DatabaseDataSet.java:305)
...

尽管我添加了属性"hibernate.hbm2ddl.auto=create-drop",但表似乎没有自己创建。有趣的是,如果数据集引用一个由实体定义的表,我就不会遇到这个问题:

@Entity
@Table(name = "users")
public class UserRecord { ... }

我通过指定DataSourceInitializer Bean来解决这个问题,该Bean运行用于设置表的sql文件:

@Configuration
public class RepoNativeQueryDataSourceInitializer {
@Bean
public DataSourceInitializer dataSourceInitializer(final DataSource dataSource) {
ResourceDatabasePopulator resourceDatabasePopulator = new ResourceDatabasePopulator();
resourceDatabasePopulator.addScript(new ClassPathResource("/schemas/schema.sql"));
DataSourceInitializer dataSourceInitializer = new DataSourceInitializer();
dataSourceInitializer.setDataSource(dataSource);
dataSourceInitializer.setDatabasePopulator(resourceDatabasePopulator);
return dataSourceInitializer;
}
}

在引用的SQL文件(src/test/resources/schemas/schema.sql)中,我也尝试先删除表,以防它们已经由JPA/Hibernate创建。这也让我摆脱了任何我不想处理的约束:

drop table if exists EXAMPLE_TABLE;
create table EXAMPLE_TABLE
(
EXAMPLE_TABLE_ID                 NUMBER(20),
)
...

我最终的测试类配置看起来像这样:

@RunWith(SpringJUnit4ClassRunner.class)
@ActiveProfiles("test")
@SpringBootTest
@ContextConfiguration(classes = {Application.class, RepoTestApplication.class, RepoNativeQueryDataSourceInitializer.class})
@TestExecutionListeners({DbUnitTestExecutionListener.class, DependencyInjectionTestExecutionListener.class})
@TestPropertySource(properties = {"spring.jpa.properties.hibernate.show_sql=true", "server.port=8445"})
@DatabaseSetup("classpath:datasets/AllMyDataForTheTests.xml")
public class StuffRepositoryTest {
@Autowired
StuffRepository stuffRepository;
...
}

最新更新