ITPub博客

首页 > 应用开发 > Java > J2EE中使用Spring AOP框架和EJB组件(5)

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

原创 Java 作者:lonlux2 时间:2007-06-20 19:24:42 0 删除 编辑

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

[@more@]

在测试用例类的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组件,并断言返回的结果。

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

测试baseTradeManageryahooFeed期望
调用返回抛出调用返回抛出结果t异常
1true0.22-false--0.22-
2true-e1false---e1
3truenull-true0.33-0.33-
4truenull-truenull-null-
5truenull-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团队管理,或者直接根据需求生成。

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/7839366/viewspace-919845/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
  • 博文量
    157
  • 访问量
    72350