大部分的Seam應(yīng)用程序至少需要兩種類型的自動測試:單元測試(unit test)是隔離測試特定的Seam組件,和腳本化的集成測試(integration test)是綜合地測試應(yīng)用中所有的Java層面(即除了表現(xiàn)層之外的所有內(nèi)容)。
兩種類型的測試都很容易編寫。
31.1. Seam組件的單元測試
所有的Seam組件都是簡單Java對象(POJO)。如果你想簡化單元測試,那么這是個極好的開端,而且Seam將其重點放在組件間交互的雙向注入和上下文對象的訪問上,這使得Seam的組件在脫離其正常運行環(huán)境時,也可以很容易地被測試。
思考如下的Seam組件:
@Stateless
@Scope(EVENT)
@Name("register")
public class RegisterAction implements Register
{
private User user;
private EntityManager em;
@In
public void setUser(User user) {
this.user = user;
}
@PersistenceContext
public void setBookingDatabase(EntityManager em) {
this.em = em;
}
public String register()
{
List existing = em.createQuery("select username from User where username=:username")
.setParameter("username", user.getUsername())
.getResultList();
if (existing.size()==0)
{
em.persist(user);
return "suclearcase/" target="_blank" >ccess";
}
else
{
return null;
}
}
}
測試上述組件的TestNG測試如下:
public class RegisterActionTest
{
@Test
public testRegisterAction()
{
EntityManager em = getEntityManagerFactory().createEntityManager();
em.getTransaction().begin();
User gavin = new User();
gavin.setName("Gavin King");
gavin.setUserName("1ovthafew");
gavin.setPassword("secret");
RegisterAction action = new RegisterAction();
action.setUser(gavin);
action.setBookingDatabase(em);
assert "success".equals( action.register() );
em.getTransaction().commit();
em.close();
}
private EntityManagerFactory emf;
public EntityManagerFactory getEntityManagerFactory()
{
return emf;
}
@BeforeClass
public void init()
{
emf = Persistence.createEntityManagerFactory("myResourceLocalEntityManager");
}
@AfterClass
public void destroy()
{
emf.close();
}
}
Java Persistence API可以與Java SE和Java EE一起使用 — 當上述組件在應(yīng)用服務(wù)器(Java EE)中使用時,由容器來負責(zé)事務(wù)管理;然而,在單元測試(Java SE)里,事務(wù)必須顯式地使用本地資源實體管理器來進行管理。 這要求在persistence.xml進行配置。
Seam的組件通常不直接依賴于容器的基礎(chǔ)設(shè)施,因此大部分的單元測試跟上述一樣容易。