Java 为什么不注射EntityManager?

Java 为什么不注射EntityManager?,java,jpa,Java,Jpa,这是我要测试的类: @Stateless public class Finder { @PersistenceContext(unitName = "abc") EntityManager em; public String read(int i) { return this.em.find(Employee.class, i).getName(); } } 这是单元测试: public class FinderTest { @Test public void te

这是我要测试的类:

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

public class FinderTest {
  @Test public void testReadingWorks() {
    Finder f = new Finder();
    String name = f.find(1);
    assert(name.length() > 0);
  }
}
问题是EntityManager没有被注入,并且在测试期间为
NULL
。我做错了什么


另外,事实上,我不明白到底谁将注入EntityManager。单元测试由JUnit在任何容器之外启动。。。也许我必须在测试中手动注入
em

EntityManager的注入只在托管bean中起作用,因为您使用
new
创建查找程序时不涉及任何容器。您可以在这里使用EntityManagerFactory自己创建EntityManager,或者使用类似的可嵌入容器

事实上,我不知道到底是谁将注入EntityManager。单元测试由JUnit在任何容器之外启动。。。也许我必须在测试中手动注入em

因为您的测试正在耗尽容器,所以没有人会注入任何内容,所以您必须手动进行。这不是一件坏事,也不难

外箱 下面是一个基类,您可以扩展它以获得
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();
        }
    }

}
在容器中使用EJBContainer API 另一个选项是在容器中运行测试,使用EJB3.1API启动嵌入式容器。请参阅Arun的(您需要做更多的工作来设置数据源)

在容器中使用Arquillian
或者你可以用。请看一看,了解一些想法。今天早上我测试了这种方法,发现它对于真实的集成测试非常有趣(但容器内测试通常比较慢,我不会把它们用于所有测试,但我开始喜欢Arquillian)。

您的持久化单元名为“abc”吗?我从哪里获得
EntityManagerFactory
,这个链接更相关:@Vincenzo也是一个很好的链接,这里的例子只是一个注释。如果您使用的是Arquillian,则在不使用
@RunAsClient
的情况下运行TestClass或测试本身非常重要,否则不会注入EntityManager。还有一个工作示例可供评估:对不起,我知道这是一个老话题。您知道为什么在@RunAsClient时不注入EntityManager吗?有没有一种方法可以让他们这么做?