我正在尝试使用JUnit测试我的会话Bean,但我不能。我尝试了很多方法,但仍然有一些例外。 这就是我需要的:
@PersistenceContext
并使用EntityManager
有人可以提供一个简单而简短的通用测试示例吗?我已经阅读了很多内容,但是我总是收到错误(当我调用类似NullPointerException
的方法时,EntityManager
得到sessionBean.method()
(例如entityManager.find(...)
}}),或者我无法初始化Context
或其他PersistenceException
)。
答案 0 :(得分:4)
您可能对Antonio Goncalves的最新帖子感兴趣:
WYTIWYR : What You Test Is What You Run
它告诉我使用以下方法使用EntityManager测试EJB:
答案 1 :(得分:1)
我解决了创建Stateless Session Bean
并将其Entity Manager
注入测试类的问题。我发布代码以防有人需要它:
@Stateless(name = "TestProxy")
@Remote({TestProxyRemote.class})
public class TestProxy implements TestProxyRemote {
@PersistenceContext(unitName = "mph")
private EntityManager em;
@Override
public void persist(Object o) {
em.persist(o);
}
@Override
public void clear() {
em.clear();
}
@Override
public void merge(Object o) {
em.merge(o);
}
@Override
@SuppressWarnings({ "rawtypes", "unchecked" })
public Object find(Class classe, String key) {
return em.find(classe, key);
}
@Override
@SuppressWarnings({ "rawtypes", "unchecked" })
public Object find(Class classe, long key) {
return em.find(classe, key);
}
@SuppressWarnings("rawtypes")
@Override
public List getEntityList(String query) {
Query q = em.createQuery(query);
return q.getResultList();
}
}
public class MyTest {
@BeforeClass
public static void setUpBeforeClass() throws NamingException {
Properties env = new Properties();
env.setProperty(Context.INITIAL_CONTEXT_FACTORY,"org.jnp.interfaces.NamingContextFactory");
env.setProperty(Context.PROVIDER_URL, "localhost:1099");
env.setProperty("java.naming.factory.url.pkgs","org.jboss.naming:org.jnp.interfaces");
jndiContext = new InitialContext(env);
try {
proxy = (TestProxyRemote) jndiContext.lookup("TestProxy/remote");
} catch (NamingException e) {
e.printStackTrace();
}
}
}
然后我可以使用proxy.find()
来获取我需要的实体,o proxy.getEntityList()
来执行查询以检索实体的所有实例。或者,如果我愿意,我可以添加其他方法。
答案 2 :(得分:0)
Unitils为JPA提供了非常酷的支持。 Unitils可以与JUnit或TestNG一起使用,如果你需要一个模拟框架,Unitils提供自己的模拟模块以及对EasyMock的支持。
@JpaEntityManagerFactory(persistenceUnit = "testPersistenceUnit")
@DataSet(loadStrategy = RefreshLoadStrategy.class)
public class TimeTrackerTest extends UnitilsTestNG {
@TestedObject
private TimeTrackerBean cut = new TimeTrackerBean();
@InjectInto(target="cut",property="em")
@PersistenceContext
private EntityManager em;
@Test
@DataSet("TimeTrackerTest.testAddTimeSlot.xml")
public void yourTest() {
...
}
}
@JpaEntityManagerFactory - 用于指定持久性单元。它会自动从项目类路径中获取persistence.xml。 @DataSet - 万一你需要加载任何测试数据,你可以使用它。 @TestedObject - 标记您的Class Under Test @PersistenceContext - 从persistence.xml中的配置 - PersistenceUnit自动创建EntityManager实例。 @InjectInto - 将em实例注入目标(剪切)
有关更多信息,请参阅this。
希望这有帮助。
答案 3 :(得分:0)
我正在使用Needle。如果你想模仿其他对象,它适用于Mockito和EasyMock。
首先我为测试编写一个persistencte.xml(src / test / resources / META-INF),如下所示:
<persistence-unit name="rapPersistenceTest" transaction-type="RESOURCE_LOCAL">
<properties>
<property name="javax.persistence.jdbc.driver" value="org.h2.Driver"/>
<property name="javax.persistence.jdbc.url" value="jdbc:h2:~/test"/>
...
</properties>
</persistence-unit>
在我的Junit-Testclass中,我写道:
public class DaoNeedleTest {
//here Needle will create persistenceContext for your testclass
public static DatabaseRule databaseRule = new DatabaseRule("rapPersistenceTest");
//here you can get the entityManager to manipulate data directly
private final EntityManager entityManager = databaseRule.getEntityManager();
@Rule
public NeedleRule needleRule = new NeedleRule(databaseRule);
//here you can instantiate your daoService
@ObjectUnderTest
DAOService daoService;
@Test
public void test() {
//if your method needs a transaction here you can get it
entityManager.getTransaction().begin();
daoService.yourMethod();
entityManager.getTransaction().commit();
}
您还需要src / test / resources中的Needle-configuration文件,您可以在其中告诉您正在使用哪种Mock-provider。例如。我正在使用Mockito:
mock.provider=de.akquinet.jbosscc.needle.mock.MockitoProvider
就是这样。