频 道 直 达 - 新闻 - 读书 - 培训 - 教程 - 前沿 - 组网 - 系统应用 - 安全 - 编程 - 存储 - 操作系统 - 数据库 - 服务器 - 专题 - 产品 - 案例库 - 技术圈 - 博客 - BBS
51CTO.COM_中国领先的IT技术网站
找资料:

J2EE中使用Spring AOP框架和EJB组件(5)

作者: Eugene Kuleshov 出处:BEA  (  ) 砖  (  ) 好  评论 ( ) 条  进入论坛
更新时间:2006-10-25 18:22
关 键 词:J2EE  Spring  AOP  EJB
阅读提示:本文介绍了一种把J2EE应用程序中的EJB转换为Spring托管组件的方法,以及转换之后可以采用的强大技术。它还给出了几个实际的例子,说明如何借助于Spring的AOP框架、应用面向方面的方法来扩展J2EE应用程序,并在不修改现有代码的情况下实现新的业务需求。

在测试用例类的setUp()方法中,我们将使用baseTradeManager和yahooFeed组件的模仿对象来初始化StubPostProcessor,而这两个组件是使用jMock API创建的。然后,我们就可以创建ClassPathXmlApplicationContext(配置其使用BeanPostProcessor)来实例化一个tradeManager组件。产生的tradeManager组件将使用模仿后的依赖性。

这种方法不仅允许孤立要测试的组件,还可以确保在Spring bean配置中正确定义通知。实际上,要在不模拟大量容器基础架构的情况下使用这样的方法来测试在EJB组件中实现的业务逻辑是不可能的:

public class ForeignTradeAdviceTest extends TestCase {
TradeManager tradeManager;
private Mock baseTradeManagerMock;
private Mock yahooFeedMock;

protected void setUp() throws Exception {
super.setUp();

baseTradeManagerMock = new Mock(TradeManager.class, "baseTradeManager");
TradeManager baseTradeManager = (TradeManager) baseTradeManagerMock.proxy();

yahooFeedMock = new Mock(TradeManager.class, "yahooFeed");
TradeManager yahooFeed = (TradeManager) yahooFeedMock.proxy();

Map stubs = new HashMap();
stubs.put("yahooFeed", yahooFeed);
stubs.put("baseTradeManager", baseTradeManager);

ConfigurableApplicationContext ctx = new ClassPathXmlApplicationContext(CTX_NAME);
ctx.getBeanFactory().addBeanPostProcessor(new StubPostProcessor(stubs));

tradeManager = (TradeManager) proxyFactory.getProxy();
}
... 

在实际的testAdvice()方法中,可以为模仿对象指定期望并验证(例如)baseTradeManager上的getPrice()方法是否返回null,然后yahooFeed上的getPrice()方法也将被调用:

public void testAdvice() throws Throwable {
String symbol = "testSymbol";
BigDecimal expectedPrice = new BigDecimal("0.222");

baseTradeManagerMock.expects(new InvokeOnceMatcher()).method("getPrice")
.with(new IsEqual(symbol)).will(new ReturnStub(null));

yahooFeedMock.expects(new InvokeOnceMatcher()).method("getPrice")
.with(new IsEqual(symbol)).will(new ReturnStub(expectedPrice));

BigDecimal price = tradeManager.getPrice(symbol);
assertEquals("Invalid price", expectedPrice, price);
baseTradeManagerMock.verify();
yahooFeedMock.verify();
}

这段代码使用jMock约束来指定,baseTradeManagerMock期望只使用一个等于symbol的参数调用getPrice()方法一次,而且这次调用将返回null。类似地,yahooFeedMock也期望对同一方法只调用一次,但是返回expectedPrice。这允许在setUp()方法中运行所创建的tradeManager组件,并断言返回的结果。

这个测试用例很容易参数化,从而涵盖所有可能的用例。注意,当组件抛出异常时,可以很容易地声明期望。

测试 baseTradeManager yahooFeed 期望
调用 返回 抛出 调用 返回 抛出 结果t 异常
1 true 0.22 - false - - 0.22 -
2 true - e1 false - - - e1
3 true null - true 0.33 - 0.33 -
4 true null - true null - null -
5 true null - true - e2 - e2

可以使用这个表更新测试类,使其使用一个涵盖了所有可能场景的参数化序列:

...   
public static TestSuite suite() {
BigDecimal v1 = new BigDecimal("0.22");
BigDecimal v2 = new BigDecimal("0.33");

RuntimeException e1 = new RuntimeException("e1");
RuntimeException e2 = new RuntimeException("e2");

TestSuite suite = new TestSuite(ForeignTradeAdviceTest.class.getName());
suite.addTest(new ForeignTradeAdviceTest

(true, v1,   null, false, null, null, v1,   null));
suite.addTest(new ForeignTradeAdviceTest

(true, null, e1,   false, null, null, null, e1));
suite.addTest(new ForeignTradeAdviceTest

(true, null, null, true,  v2,   null, v2,   null));
suite.addTest(new ForeignTradeAdviceTest

(true, null, null, true,  null, null, null, null));
suite.addTest(new ForeignTradeAdviceTest

(true, null, null, true,  null, e2,   null, e2));
return suite;
}

public ForeignTradeAdviceTest(
boolean baseCall, BigDecimal baseValue, Throwable baseException,
boolean yahooCall, BigDecimal yahooValue, Throwable yahooException,
BigDecimal expectedValue, Throwable expectedException) {
super("test");

this.baseCall = baseCall;
this.baseWill = baseException==null ? 
(Stub) new ReturnStub(baseValue) : new ThrowStub(baseException);
this.yahooCall = yahooCall;
this.yahooWill = yahooException==null ? 
(Stub) new ReturnStub(yahooValue) : new ThrowStub(yahooException);
this.expectedValue = expectedValue;
this.expectedException = expectedException;
}

public void test() throws Throwable {
String symbol = "testSymbol";

if(baseCall) {
baseTradeManagerMock.expects(new InvokeOnceMatcher())
.method("getPrice").with(new IsEqual(symbol)).will(baseWill);
}

if(yahooCall) {
yahooFeedMock.expects(new InvokeOnceMatcher())
.method("getPrice").with(new IsEqual(symbol)).will(yahooWill);
}

try {
BigDecimal price = tradeManager.getPrice(symbol);
assertEquals("Invalid price", expectedValue, price);
} catch(Exception e) {
if(expectedException==null) {
throw e;
}
}
baseTradeManagerMock.verify();
yahooFeedMock.verify();
}

public String getName() {
return super.getName()+" "+
baseCalled+" "+baseValue+" "+baseException+" "+
yahooCalled+" "+yahooValue+" "+yahooException+" "+
expectedValue+" "+expectedException;
}
...

在更复杂的情况下,上面的测试方法可以很容易地扩展为大得多的输入参数集合,而且它仍然会立刻运行且易于管理。此外,把所有参数移入一个外部配置文件或者甚至Excel电子表格是合理的做法,这些配置文件或电子表格可以由QA团队管理,或者直接根据需求生成。


共6页: 上一页 [1] [2] [3] [4] 5 [6] 下一页
【内容导航】
发表
查看
我也说两句

匿名发表

(如果看不清请点击图片进行更换)


中 国 领 先 的 IT 技 术 网 站 ·
技 术 成 就 梦 想
·Java基础教程 (查看52371次)
·UML类图详解 (查看46839次)
·Java编程开发手册 (查看25118次)
·UML统一建模语言 (查看24099次)
·C#技术开发指南 (查看22406次)
·Java编程开发手册 (1195个砖)
·Java基础教程 (429个砖)
·C#技术开发指南 (304个砖)
·PB开发教程 (220个砖)
·.NET开发手册 (217个砖)
·Java编程开发手册 (653个好)
·Java基础教程 (569个好)
·.NET开发手册 (251个好)
·PB开发教程 (209个好)
·Delphi开发技术手册 (174个好)
订阅技术快讯
电子杂志下载
名称:网络安全精品应用黄皮书
简介:《2007精品网络安全黄皮书》包括了9个大类24个小类, 800余篇文章,内容包含了熊猫烧香病毒、DDOS攻击、ARP病等热点问题的介绍及解决方案。从病毒查杀、防范、系统、数据等各方面的安全设置到黑客技术的了解、防范,涉及到了安全应用的全部领域, 由浅至深内容全面。
名称:Vista精品应用黄皮书
简介:《Vista精品应用黄皮书》囊括了Vista的各方面内容。此次的精简版,是将里面的内容做了提取,便于用户下载和使用。内容包含了各种Vista的安装与实施、技巧与解析以及各种Vista相关学习文档和相关软件的安全下载。该电子书是了解和应用Vista人员必备的工具手册,并且也是第一本
名称:2006中国IT论坛精品集合
简介:本书由“51CTO论坛推广联盟”制作完成。书中所有内容均来自各联盟成员的论坛(网站)。制作本书的目的是为了集中大家的优势资源,将更多更精彩的内容带给广大技术爱好者。本书是联盟成立以来制作的第一本书。
关键字阅读
频道精选
主编信箱 热线:010-66476606 告诉我们您想看的:专题 文章
关于我们 | 诚聘英才 | 联系我们 | 网站大事 | 意见反馈 | 网站地图
Copyright©2005-2007 51CTO.COM 版权所有