我正在尝试在DAO类中注入一个实体管理器并使用焊接容器对其进行测试,但我仍然遇到以下异常:
org.jboss.weld.exceptions.NullInstanceException:WELD-000044无法从org.jboss.weld.bean-se-module-ProducerField-com.playground.cdi_tutorial.beans.Resources.em获取实例 在org.jboss.weld.bean.builtin.CallableMethodHandler.invoke(CallableMethodHandler.java:60) 在org.jboss.weld.util.CleanableMethodHandler.invoke(CleanableMethodHandler.java:43) 在javax.persistence.EntityManager _ $$ _ javassist_2.createQuery(EntityManager _ $$ _ javassist_2.java) 在com.playground.cdi_tutorial.model.EventDAO.getAllEvents(EventDAO.java:22) 在com.playground.cdi_tutorial.beans.ValidationService.validateEvenNumbers(ValidationService.java:23) 在com.playground.cdi_tutorial.beans.MyFactory.sayHi(MyFactory.java:15) 在com.playground.cdi_tutorial.beans.MyFactoryTest.should_say_bye(MyFactoryTest.java:26) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 在java.lang.reflect.Method.invoke(Method.java:601) 在org.junit.runners.model.FrameworkMethod $ 1.runReflectiveCall(FrameworkMethod.java:44) 在org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) 在org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41) 在org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20) 在org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79) 在org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71) 在org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49) 在org.junit.runners.ParentRunner $ 3.run(ParentRunner.java:193) 在org.junit.runners.ParentRunner $ 1.schedule(ParentRunner.java:52) 在org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191) 在org.junit.runners.ParentRunner.access $ 000(ParentRunner.java:42) 在org.junit.runners.ParentRunner $ 2.evaluate(ParentRunner.java:184) 在org.junit.runners.ParentRunner.run(ParentRunner.java:236) 在org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) 在org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) 在org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) 在org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) 在org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) 在org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
我尝试按如下方式注入实体管理器:
@Inject
@EmProducer
EntityManager em;
其中EmProducer看起来像这样:
@Qualifier
@Target({ TYPE, METHOD, PARAMETER, FIELD })
@Retention(RUNTIME)
@Documented
public @interface EmProducer {
public static final String UNIT_NAME = "cdi-tutorial";
}
生产者类看起来像这样:
public class Resources {
@Produces
@EmProducer
@PersistenceContext(unitName = EmProducer.UNIT_NAME)
private EntityManager em;
...
}
在我的测试中,当遇到这行代码时,查询q = em.createQuery(“来自员工”);我得到了上面的例外。实体管理器em虽然不是null。
PS:我使用WeldJUnit4Runner(http://www.hostettler.net/blog/2012/04/02/how-to-test-a-jsf-named-bean/)来运行我的测试。
我真的很感谢你的帮助。
谢谢!
答案 0 :(得分:1)
我建议使用Arquillian进行此类测试。它使容器内测试变得非常容易(并且快速)。你可以正常注入EntityManager,Arquillian负责其余的工作......