三、实战StrutsTestCase
为了使用StrutsTestCase来测试这个行为,我们创建一个扩展类MockStrutsTestCase的新类。这个类提供一系列方法来构建一个模拟的HTTP请求,调用相应的Struts行为以及一旦在行为完成时校验应用程序状态。
可以设想有一个在线的具有多条件查找功能的住所数据库。这个查找函数是通过/search.do行为实现的。这个行为将基于指定的条件完成一次多条件查 找,并把结果列表放置在一个称为results的请求范围属性中。例如,下列URL应该显示一个在法国的所有的住所结果列表:
/search.do?country=FR
现在,假定我们想要使用一个测试驱动的方式来实现这个方法。我们创建该行为类并更新Struts配置文件。我们还编制测试实例来测试(空的)这个行为 类。通过使用一种严格的测试驱动的开发方法,我们可以首先创建测试实例,然后实现代码来匹配该测试实例。在实践中,具体的顺序可能因要测试的代码而有所不 同。
起始的测试情形看去如下样子:
public void testSearchByCountry() {
setRequestPathInfo("/search.do");
addRequestParameter("country", "FR");
actionPerform();
}
在此,我们建立要调用的路径(setRequestPathInfo())并且添加一请求参数(addRequestParameter())。然后, 我们用actionPerform()来调用行为类。这将验证Struts配置并且调用相应的行动类,但是将不测试该行为的实际所做。为此,我们需要验证 行动的结果。
在此,我们检查三件事情:
·不存在ActionError消息(verifyNoActionErrors())。
·返回"success"forward。
·results属性被放置到请求范围中。
如果我们正在使用tiles,我们也可以通过使用verifyTilesForward()来保证"success"forward实际上指定正确的tiles定义:
public void testSearchByCountry() {
setRequestPathInfo("/search.do");
addRequestParameter("country", "FR");
actionPerform();
verifyNoActionErrors();
verifyTilesForward("success", "accommodation.list.def");
assertNotNull(request.getAttribute("results"));
}
在实践中,我们可能想在该测试结果上实现特定的商业测试。例如,假定结果属性是一个List-它包含一列约100个Hotel域对象,并且我们想要保证所有在该列表中的宾馆都在法国。为了实现这种类型的测试,代码将非常相似于标准JUnit测试:
public void testSearchByCountry() {
setRequestPathInfo("/search.do");
addRequestParameter("country", "FR");
actionPerform();
verifyNoActionErrors();
verifyForward("success");
assertNotNull(request.getAttribute("results"));
List results = (List) request.getAttribute("results");
assertEquals(results.size(), 100);
for (Iterator iter = results.iterator();
iter.hasNext();) {
Hotel hotel = (Hotel) iter.next();
assertEquals(hotel.getCountry, TestConstants.FRANCE);
...
}
} 当你测试更复杂的情形时,你可能想要测试系列化的行为。例如,假定用户在法国查询所有的宾馆并且点击一个入口来显示相应的查询细节。假定我们有一个Struts行为来显示一个给定宾馆的细节信息,可以作如下调用:
/displayDetails.do?id=123456
通过使用StrutsTestCase,我们能够容易地在相同的测试情形下模仿一系列的行为-一个用户在法国查询所有的宾馆,然后点击一个入口来显示相应的查询细节:
public void testSearchAndDisplay() {
setRequestPathInfo("/search.do");
addRequestParameter("country", "FR");
actionPerform();
verifyNoActionErrors();
verifyForward("success");
assertNotNull(request.getAttribute("results"));
List results = (List) request.getAttribute("results");
assertEquals(results.size(),100);
Hotel hotel = (Hotel) results.get(0);
setRequestPathInfo("/displayDetails.do");
addRequestParameter("id", hotel.getId());
actionPerform();
verifyNoActionErrors();
verifyForward("success");
Hotel hotel = (Hotel)request.getAttribute("hotel");
assertNotNull(hotel);
...
}