Java 如何在与testcontainers的集成测试中管理EM或EMF?
我有java web应用程序,我想为服务层编写集成测试。我决定使用,所以在测试中我想调用服务,它将与docker容器中的数据库一起工作 我的测试类如下面的示例所示Java 如何在与testcontainers的集成测试中管理EM或EMF?,java,integration-testing,entitymanager,testcontainers,Java,Integration Testing,Entitymanager,Testcontainers,我有java web应用程序,我想为服务层编写集成测试。我决定使用,所以在测试中我想调用服务,它将与docker容器中的数据库一起工作 我的测试类如下面的示例所示 @Testcontainers class ITPlayerServiceImpl { @Container private static final PostgreSQLContainer POSTGRE_SQL_CONTAINER = new PostgreSQLContainer() .w
@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
我需要在容器中创建连接到DB的EMF,然后将该EMF中的EM填充到测试的服务中
@Stateless
public class PlayerServiceImpl implements PlayerService {
@PersistenceContext(unitName = "persistence_unit_name")
private EntityManager entityManager;
//Methods
感谢您的帮助或提示。经过一些调查和测试,我以下面的解决方案结束
@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();
}
}
}
@TestMethodOrder(methodorder.OrderAnnotation.class)
@测试容器
类ITApplicationUserService{
@容器
私有静态最终PostgreSQLContainer POSTGRE_SQL_CONTAINER=new PostgreSQLContainer()
.withDatabaseName(“someDatabase”)
.withUsername(“someUsername”)
.withPassword(“somePassword”);
//集成测试的EMF
私有静态实体管理器工厂emf;
//测试服务的EM
私有静态实体管理器实体管理器;
//测试服务
私有静态ApplicationUserServiceImpl applicationUserService=新ApplicationUserServiceImpl();
//用于测试的对象
专用静态应用程序用户测试应用程序用户;
@以前
静态void init(){
//属性,这将使EM连接到POSTGRE\u SQL\u容器
映射属性=新的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(“eclipseelink.logging.level”、“FINE”);
//我们需要在POSTGRE\u SQL\u容器中创建新的空模式
properties.put(“javax.persistence.schema generation.database.action”、“create”);
//创建EMF
emf=Persistence.createEntityManagerFactory(“集成测试”,属性);
//测试用播放器
testingApplicationUser=新的ApplicationUser();
测试applicationuser.setLogin(“loginName”);
正在测试Application User.setEmail(“something@somewhere.com");
测试应用程序用户设置密码(“123456”);
}
@试验
@订单(1)
void saveNewApplicationUserTest(){
assertTrue(testingApplicationUser.getId()==null);
ApplicationUser ApplicationUser=applicationUserService.saveApplicationUser(测试ApplicationUser);
assertTrue(applicationUser.getId()!=null);
}
@试验
@订单(2)
void getApplicationUsers(){
assertTrue(applicationUserService.getAllApplicationUsers().size()=1);
}
@之前
私有void startTransaction()引发IllegaAccessException,NoSuchFieldException{
entityManager=emf.createEntityManager();
//我们将在测试服务中声明EM字段
//测试类中的电磁场不是公共的,也不应该是公共的。我们将对电磁场的总体使用反射。
字段emField=applicationUserService.getClass().getDeclaredField(“entityManager”);
emField.setAccessible(true);
emField.set(applicationUserService,entityManager);
entityManager.getTransaction().begin();
}
@之后
私人无效委托交易(){
if(entityManager.getTransaction().isActive()){
entityManager.getTransaction().commit();
entityManager.close();
}
}
}
经过一些调查和测试,我以下面的解决方案结束
@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();
}
}
}
@TestMethodOrder(methodorder.OrderAnnotation.class)
@测试容器
类ITApplicationUserService{
@容器
私有静态最终PostgreSQLContainer POSTGRE_SQL_CONTAINER=new PostgreSQLContainer()
.withDatabaseName(“someDatabase”)
.withUsername(“someUsername”)
.withPassword(“somePassword”);
//集成测试的EMF
私有静态实体管理器工厂emf;
//测试服务的EM
私有静态实体管理器实体管理器;
//测试服务
私有静态ApplicationUserServiceImpl applicationUserService=新ApplicationUserServiceImpl();
//用于测试的对象
专用静态应用程序用户测试应用程序用户;
@以前
静态void init(){
//属性,这将使EM连接到POSTGRE\u SQL\u容器
映射属性=新的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(“eclipseelink.logging.level”、“FINE”);
//我们需要在POSTGRE\u SQL\u容器中创建新的空模式
properties.put(“javax.persistence.schema generation.database.action”、“create”);
//创建EMF
emf=Persistence.createEntityManagerFactory(“集成测试”,属性);
//测试用播放器
testingApplicationUser=新的ApplicationUser();
测试applicationuser.setLogin(“loginName”);
正在测试Application User.setEmail(“something@somewhere.com");
测试应用程序用户设置密码(“123456”);
}
@试验
@订单(1)
void saveNewApplicationUserTest(){
assertTrue(testingApplicationUser.getId()==null);
ApplicationUser ApplicationUser=applicationUserService.saveApplicationUser(测试ApplicationUser);
assertTrue(applicationUser.getId()!=null);
}
@试验
@订单(2)
void getApplicationUsers(){
assertTrue(applicationUserService.getAllApplicationUs