Flex,Flexunit:如何测试事件被分派两次?

时间:2009-07-22 19:16:36

标签: flex unit-testing events testing flexunit

我正在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);
}

2 个答案:

答案 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);
}