基于内存和测试
现在是最有趣的。在测试 Hibernate 代码时,通常您不想使用真正的基础,而是使用某种实现最少功能的存根。
您能想象一个实现大部分 SQL Server 标准的存根吗?我没有。但是,内存数据库本身就非常出色。它的工作原理大致是这样的:
- 在@BeforeAll 方法中,我们初始化内存中的数据库连接。
- 在@BeforeEach 方法中,我们获取会话并打开一个事务。
- 在@Test 方法中,我们使用当前会话和事务。
- 在@AfterEach 方法中,我们提交事务。
- 最后,在 AfterAll 方法中,我们关闭与数据库的连接。
以下是测试准备工作的样子:
@Test
public class HelloTest {
private static SessionFactory sessionFactory = null;
private Session session = null;
@BeforeAll
static void setup(){
try {
StandardServiceRegistry standardRegistry = new StandardServiceRegistryBuilder()
.configure("hibernate-test.cfg.xml").build();
Metadata metadata = new MetadataSources(standardRegistry)
.addAnnotatedClass(Employee.class)
.getMetadataBuilder()
.build();
sessionFactory = metadata.getSessionFactoryBuilder().build();
} catch (Throwable ex) {
throw new ExceptionInInitializerError(ex);
}
}
@BeforeEach
void setupThis(){
session = sessionFactory.openSession();
session.beginTransaction();
}
@AfterEach
void tearThis(){
session.getTransaction().commit();
}
@AfterAll
static void tear(){
sessionFactory.close();
}
这就是测试本身在 Hibernate 的作用下的样子:
@Test
public class HelloTest {
@Test
void createSessionFactoryWithXML() {
Employee emp = new Employee();
emp.setEmail("demo-user@mail.com");
emp.setFirstName("demo");
emp.setLastName("user");
Assertions.assertNull(emp.getEmployeeId());
session.persist(emp);
Assertions.assertNotNull(emp.getEmployeeId());
}
}
测试数据
您还可以使用测试数据填充测试数据库。
通常为此制作两个sql文件:
- schema.sql 包含一个在数据库中创建表的脚本
- test-data.sql 包含一个用测试数据填充表的脚本
表创建和测试数据通常被分离到不同的文件中,因为他们自己的测试数据组几乎总是出现在不同的测试组中。
执行这些文件如下所示:
void runSqlScriptFile(String filePath){
String sqlScript = new String( Files.readAllBytes(Paths.get(filePath)) );
Session session = sessionFactory.openSession();
Query query = session.createNativeQuery("BEGIN " + sqlScript + " END;");
query.executeUpdate()
}
你的设置方法会有所改变:
@BeforeAll
static void setup(){
try {
StandardServiceRegistry standardRegistry = new StandardServiceRegistryBuilder()
.configure("hibernate-test.cfg.xml").build();
Metadata metadata = new MetadataSources(standardRegistry)
.addAnnotatedClass(Employee.class)
.getMetadataBuilder()
.build();
sessionFactory = metadata.getSessionFactoryBuilder().build();
runSqlScriptFile(“scema.sql”);
runSqlScriptFile(“test-data.sql”);
} catch (Throwable ex) {
throw new ExceptionInInitializerError(ex);
}
}
GO TO FULL VERSION