简体   繁体   English

为什么不注入EntityManager?

[英]Why EntityManager is not injected?

This is the class I'm trying to test: 这是我要测试的课程:

@Stateless
public class Finder {
  @PersistenceContext(unitName = "abc")
  EntityManager em;
  public String read(int i) {
    return this.em.find(Employee.class, i).getName();
  }
}

This is the unit test: 这是单元测试:

public class FinderTest {
  @Test public void testReadingWorks() {
    Finder f = new Finder();
    String name = f.find(1);
    assert(name.length() > 0);
  }
}

The problem is that EntityManager is not injected, and is NULL during testing. 问题是EntityManager没有注入,并且在测试期间是NULL What am I doing wrong? 我究竟做错了什么?

ps. PS。 Actually, I don't understand who exactly is going to inject EntityManager. 实际上,我不明白谁将要注入EntityManager。 The unit test is started by JUnit, outside of any container... Maybe I have to inject em manually in the test? 单元测试由JUnit在任何容器之外启动......也许我必须在测试中手动注入em

Injection of EntityManagers only works in managed beans, since you are creating the Finder with new no container is involved. EntityManagers的注入仅适用于托管bean,因为您创建的Finder包含new无容器。 You could eithere create the EntityManager yourself using the EntityManagerFactory or use a embeddable Container like OpenEJB in your unit tests . 您可以使用EntityManagerFactory自己创建EntityManager,或在单元测试中使用OpenEJB之类的可嵌入容器。

Actually, I don't understand who exactly is going to inject EntityManager. 实际上,我不明白谁将要注入EntityManager。 The unit test is started by JUnit, outside of any container... Maybe I have to inject em manually in the test? 单元测试由JUnit在任何容器之外启动......也许我必须在测试中手动注入em?

Since your test is running out container, nobody is going to inject anything, you'll have to do it manually. 由于你的测试用完容器,没有人会注入任何东西,你必须手动完成。 This is IMHO not really a bad thing, and not hard. 这是恕我直言并不是一件坏事,并不难。

Out container 出集装箱

Here is a base class that you could extend to get an EntityManager : 这是一个可以扩展以获取EntityManager的基类:

public abstract class JpaBaseRolledBackTestCase {
    protected static EntityManagerFactory emf;
    protected EntityManager em;

    @BeforeClass
    public static void createEntityManagerFactory() {
        emf = Persistence.createEntityManagerFactory("PetstorePu");
    }

    @AfterClass
    public static void closeEntityManagerFactory() {
        emf.close();
    }

    @Before
    public void beginTransaction() {
        em = emf.createEntityManager();
        em.getTransaction().begin();
    }

    @After
    public void rollbackTransaction() {

        if (em.getTransaction().isActive()) {
            em.getTransaction().rollback();
        }

        if (em.isOpen()) {
            em.close();
        }
    }

}

In container using the EJBContainer API 在容器中使用EJBContainer API

Another option would be to run your test in container , using the EJB 3.1 EJBContainer API to start an embedded container. 另一个选择是在容器中运行测试,使用EJB 3.1 EJBContainer API启动嵌入式容器。 See Arun's TOTD #128: EJBContainer.createEJBContainer: Embedded EJB using GlassFish v3 (you'll need a bit more work to setup the datasource). 请参阅Arun的TOTD#128:EJBContainer.createEJBContainer:使用GlassFish v3的嵌入式EJB (您需要更多的工作来设置数据源)。

In container using Arquillian 在使用Arquillian的容器中

Or you could use Arquillian . 或者你可以使用Arquillian Have a look at The perfect recipe for testing JPA 2: revisited for some ideas. 看一下测试JPA 2的完美配方:重新审视一些想法。 I tested this approach this morning and find it VERY interesting for real integration tests (but in container tests are typically slower and I won't use them for everything - but I'm starting to love Arquillian). 我今天早上测试了这种方法,并发现真正的集成测试非常有趣(但是在容器测试中通常较慢,我不会将它们用于所有东西 - 但我开始喜欢Arquillian)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM