在使用测试容器进行集成测试时,您如何管理 EM 或 EMF?
How you manage EM or EMF in integration testing with testcontainers?
我有 java 网络应用程序,我想为服务层编写集成测试。我决定使用 testcontainers,所以在测试中我想调用服务,它将与 docker 容器中的数据库一起工作。
我的测试 class 如下例所示。
@Testcontainers
class ITPlayerServiceImpl {
@Container
private static final PostgreSQLContainer POSTGRE_SQL_CONTAINER =
new PostgreSQLContainer()
.withDatabaseName("dbName")
.withUsername("dbUserName")
.withPassword("dbPassword");
}
已测试服务。
@Stateless
public class PlayerServiceImpl implements PlayerService {
@PersistenceContext(unitName = "persistence_unit_name")
private EntityManager entityManager;
//Methods
我需要在容器中创建连接到数据库的 EMF,然后将 EM 从该 EMF 填充到测试服务中。
感谢您的帮助或提示。
经过一些调查和测试,我以下面的解决方案结束。
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
@Testcontainers
class ITApplicationUserService {
@Container
private static final PostgreSQLContainer POSTGRE_SQL_CONTAINER = new PostgreSQLContainer()
.withDatabaseName("someDatabase")
.withUsername("someUsername")
.withPassword("somePassword");
// EMF for integration tests
private static EntityManagerFactory emf;
// EM for tested service
private static EntityManager entityManager;
// Tested service
private static ApplicationUserServiceImpl applicationUserService = new ApplicationUserServiceImpl();
// Object used for testing
private static ApplicationUser testingApplicationUser;
@BeforeAll
static void init() {
// Properties for our EMF, which will make EM connected to POSTGRE_SQL_CONTAINER
Map<String,String> properties = new HashMap<>();
properties.put("javax.persistence.jdbc.url",POSTGRE_SQL_CONTAINER.getJdbcUrl());
properties.put("javax.persistence.jdbc.user",POSTGRE_SQL_CONTAINER.getUsername());
properties.put("javax.persistence.jdbc.password",POSTGRE_SQL_CONTAINER.getPassword());
properties.put("javax.persistence.jdbc.driver",POSTGRE_SQL_CONTAINER.getDriverClassName());
properties.put("eclipselink.logging.level","FINE");
// We need create fresh empty schema in POSTGRE_SQL_CONTAINER
properties.put("javax.persistence.schema-generation.database.action","create");
// Creation of EMF
emf = Persistence.createEntityManagerFactory("integrationTesting",properties);
// Player for testing
testingApplicationUser = new ApplicationUser();
testingApplicationUser.setLogin("loginName");
testingApplicationUser.setEmail("something@somewhere.com");
testingApplicationUser.setPassword("123456");
}
@Test
@Order(1)
void saveNewApplicationUserTest() {
assertTrue(testingApplicationUser.getId()==null);
ApplicationUser applicationUser = applicationUserService.saveApplicationUser(testingApplicationUser);
assertTrue(applicationUser.getId()!=null);
}
@Test
@Order(2)
void getApplicationUsers() {
assertTrue(applicationUserService.getAllApplicationUsers().size()==1);
}
@BeforeEach
private void startTransaction() throws IllegalAccessException, NoSuchFieldException {
entityManager = emf.createEntityManager();
// We will declare field of EM in tested service
// EM field in tested class is not public and should not be. We will use reflection for population of EM.
Field emField = applicationUserService.getClass().getDeclaredField("entityManager");
emField.setAccessible(true);
emField.set(applicationUserService,entityManager);
entityManager.getTransaction().begin();
}
@AfterEach
private void commitTransaction() {
if (entityManager.getTransaction().isActive()) {
entityManager.getTransaction().commit();
entityManager.close();
}
}
}
我有 java 网络应用程序,我想为服务层编写集成测试。我决定使用 testcontainers,所以在测试中我想调用服务,它将与 docker 容器中的数据库一起工作。
我的测试 class 如下例所示。
@Testcontainers
class ITPlayerServiceImpl {
@Container
private static final PostgreSQLContainer POSTGRE_SQL_CONTAINER =
new PostgreSQLContainer()
.withDatabaseName("dbName")
.withUsername("dbUserName")
.withPassword("dbPassword");
}
已测试服务。
@Stateless
public class PlayerServiceImpl implements PlayerService {
@PersistenceContext(unitName = "persistence_unit_name")
private EntityManager entityManager;
//Methods
我需要在容器中创建连接到数据库的 EMF,然后将 EM 从该 EMF 填充到测试服务中。
感谢您的帮助或提示。
经过一些调查和测试,我以下面的解决方案结束。
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
@Testcontainers
class ITApplicationUserService {
@Container
private static final PostgreSQLContainer POSTGRE_SQL_CONTAINER = new PostgreSQLContainer()
.withDatabaseName("someDatabase")
.withUsername("someUsername")
.withPassword("somePassword");
// EMF for integration tests
private static EntityManagerFactory emf;
// EM for tested service
private static EntityManager entityManager;
// Tested service
private static ApplicationUserServiceImpl applicationUserService = new ApplicationUserServiceImpl();
// Object used for testing
private static ApplicationUser testingApplicationUser;
@BeforeAll
static void init() {
// Properties for our EMF, which will make EM connected to POSTGRE_SQL_CONTAINER
Map<String,String> properties = new HashMap<>();
properties.put("javax.persistence.jdbc.url",POSTGRE_SQL_CONTAINER.getJdbcUrl());
properties.put("javax.persistence.jdbc.user",POSTGRE_SQL_CONTAINER.getUsername());
properties.put("javax.persistence.jdbc.password",POSTGRE_SQL_CONTAINER.getPassword());
properties.put("javax.persistence.jdbc.driver",POSTGRE_SQL_CONTAINER.getDriverClassName());
properties.put("eclipselink.logging.level","FINE");
// We need create fresh empty schema in POSTGRE_SQL_CONTAINER
properties.put("javax.persistence.schema-generation.database.action","create");
// Creation of EMF
emf = Persistence.createEntityManagerFactory("integrationTesting",properties);
// Player for testing
testingApplicationUser = new ApplicationUser();
testingApplicationUser.setLogin("loginName");
testingApplicationUser.setEmail("something@somewhere.com");
testingApplicationUser.setPassword("123456");
}
@Test
@Order(1)
void saveNewApplicationUserTest() {
assertTrue(testingApplicationUser.getId()==null);
ApplicationUser applicationUser = applicationUserService.saveApplicationUser(testingApplicationUser);
assertTrue(applicationUser.getId()!=null);
}
@Test
@Order(2)
void getApplicationUsers() {
assertTrue(applicationUserService.getAllApplicationUsers().size()==1);
}
@BeforeEach
private void startTransaction() throws IllegalAccessException, NoSuchFieldException {
entityManager = emf.createEntityManager();
// We will declare field of EM in tested service
// EM field in tested class is not public and should not be. We will use reflection for population of EM.
Field emField = applicationUserService.getClass().getDeclaredField("entityManager");
emField.setAccessible(true);
emField.set(applicationUserService,entityManager);
entityManager.getTransaction().begin();
}
@AfterEach
private void commitTransaction() {
if (entityManager.getTransaction().isActive()) {
entityManager.getTransaction().commit();
entityManager.close();
}
}
}