Java 如何在与testcontainers的集成测试中管理EM或EMF?

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

我有java web应用程序,我想为服务层编写集成测试。我决定使用,所以在测试中我想调用服务,它将与docker容器中的数据库一起工作

我的测试类如下面的示例所示

@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