我正在Flex应用程序中测试一些事件调度代码,使用FlexUnit的addAsync
方法测试事件是否已分派。到目前为止,我可以确保至少有一个事件被解雇。但是,我想要更详细一些;我想确保调度我期待的事件集。是否有一个有用的测试模式(或者,甚至是不同的测试框架 - 我很灵活!)来实现这个目标吗?
我尝试了这段代码,但似乎第二次没有调用它:
protected function expectResultPropertyChange(event: Event, numberOfEvents: int = 1): void {
trace("Got event " + event + " on " + event.target + " with " + numberOfEvents + " traces left...");
assertTrue(event.type == ResponseChangedEvent.RESPONSE_CHANGED);
if (numberOfEvents > 1) {
event.target.addEventListener(ResponseChangedEvent.RESPONSE_CHANGED, addAsync(expectResultPropertyChange, 1000, numberOfEvents - 1));
}
}
public function testSomething(): void {
requiredQuestion.addEventListener(ResponseChangedEvent.RESPONSE_CHANGED, addAsync(expectResultPropertyChange, 1000, 2));
requiredQuestion.responseSelected("1", true);
requiredQuestion.responseSelected("2", true);
}
答案 0 :(得分:2)
这将是一个高级的例子,说明如何使用模拟输出的对象来解决类似的问题。显然我看不到你的代码,所以我不能给你一个确切的例子。
所以,正如我在评论中所说的那样,你可以在类中模拟出一个依赖假的异步调用,以便它们变得同步。参加以下课程
public class RequiredQuestion extends EventDispatcher
{
private var someAsynchronousObject : IAsynchronousObject;
public function RequiredQuestion(someAsynchronousObject : IAsynchronousObject = null)
{
someAsynchronousObject = someAsynchronousObject || new AsynchronousObject();
someAsynchronousObject.addEventListener(Event.COMPLETE, asyncCallComplete);
}
public function responseSelected(id : String, flag : Boolean) : void
{
//Will asynchronously fire the Event.COMPLETE event
someAsynchronousObject.startAsynchrounsCall();
}
protected function asyncCallComplete(event : Event) : void
{
dispatchEvent(new ResponseChangedEvent(ResponseChangedEvent.RESPONSE_CHANGED));
}
}
因此,默认情况下,您使用要使用的具体类,除非通过构造函数将someAsynchronousObjec注入到类中。 AsycnhronousObject可能有它自己的单元测试,或者它在外部类中,所以你不需要或者需要测试它的功能。您现在可以做的是创建一个模拟对象,该对象实现可用于伪造其行为的IAsynchronousObject。使用ASMock框架,测试看起来像这样:
public function testSomething(): void
{
var mockIAsycnhronousObject : IAsynchronousObject =
IAsynchronousObject(mockRepository.createStrict( IAsynchronousObject));
SetupResult.forEventDispatcher(mockIAsycnhronousObject);
SetupResult.forCall(mockIAsycnhronousObject.startAsynchronousCall())
.dispatchEvent(new Event(Event.COMPLETE)); // all calls to the startAsynchronousCall method and dispatch the complete event everytime it's called.
mockRepository.replayAll();
var requiredQuestion : RequiredQuestion = new RequiredQuestion(mockIAsycnhronousObject);
var callCount : int = 0;
requiredQuestion.addEventListener(ResponseChangedEvent.RESPONSE_CHANGED, function(event : ResponseChangedEvent)
{
callCount++;
});
requiredQuestion.responseSelected("1", true);
requiredQuestion.responseSelected("2", true);
assertEquals(2, callCount);
mockRepository.verifyAll();
}
这只是模拟如何帮助您进行单元测试的一个示例。虽然它对ActionScript(12月发布)来说仍然是一个非常新的东西,但是有很多关于模拟的信息。 ASMock基于.net Rhino模拟,因此如果您需要帮助,搜索Rhino模拟应该会产生更多结果。
绝对是一种不同的思维方式但是一旦你进入它,你就会想知道如果没有它们,你是如何在单元测试中获得的。
答案 1 :(得分:2)
回应评论......
如果调度事件怎么办? 直? responseSelected没有 触发一个异步事件 复合对象,它只是派遣 RESPONSE_CHANGED事件本身 直。我没看到这个怎么样 方法可以用你的嘲笑 方法。请注意,我对它很模糊 模拟测试实践原样,所以我 可能错过了一个简单的解 这里。
..在这种情况下,您不需要使用mock或addAsync。这样的事情会做:
public function testSomething(): void
{
var requiredQuestion : RequiredQuestion = new RequiredQuestion();
var callCount : int = 0;
requiredQuestion.addEventListener(ResponseChangedEvent.RESPONSE_CHANGED, function(event : ResponseChangedEvent)
{
callCount++;
});
requiredQuestion.responseSelected("1", true);
requiredQuestion.responseSelected("2", true);
assertEquals(2, callCount);
}