【问题标题】:How you manage EM or EMF in integration testing with testcontainers?在与测试容器的集成测试中,您如何管理 EM 或 EMF?
【发布时间】:2019-08-31 15:58:10
【问题描述】:

我有 java web 应用程序,我想为服务层编写集成测试。我决定使用testcontainers,所以在测试中我想调用服务,它将与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

我需要在容器中创建连接到数据库的 EMF,然后将该 EMF 中的 EM 填充到测试服务中。

感谢您的帮助或提示。

【问题讨论】:

  • 你能尝试做这样的事情吗?我相信即使通过测试容器,您也可以通过 createEMFactory 方法访问 EMF。私有静态 EntityManagerFactory 电动势; @Before public static void setup() { log.debug("创建实体管理器工厂"); emf = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT); } in.relation.to/2016/01/14/hibernate-jpa-test-case-template

标签: java integration-testing entitymanager testcontainers


【解决方案1】:

经过一些调查和测试,我以下面的解决方案结束。

@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();
        }

    }

}

【讨论】:

  • 嗨,伙计,我有同样的问题,我一直以 javax.persistence.PersistenceException: No Persistence provider for EntityManager named but I it's under my /test/resources/META-INF/persistance.xml
猜你喜欢
  • 2014-07-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-06
  • 2011-03-15
  • 1970-01-01
相关资源
最近更新 更多