Apache flex FlexUnit组件测试模式:使用addAsync还是手动初始化?

Apache flex FlexUnit组件测试模式:使用addAsync还是手动初始化?,apache-flex,unit-testing,Apache Flex,Unit Testing,我们在工作中已经使用Flex大约6个月了,我发现我的第一批涉及定制组件的FlexUnit测试倾向于遵循这种模式: import mx.core.Application; import mx.events.FlexEvent; import flexunit.framework.TestCase; public class CustomComponentTest extends TestCase { private var component:CustomComponent;

我们在工作中已经使用Flex大约6个月了,我发现我的第一批涉及定制组件的FlexUnit测试倾向于遵循这种模式:

import mx.core.Application;
import mx.events.FlexEvent;
import flexunit.framework.TestCase;

public class CustomComponentTest extends TestCase {
    private var component:CustomComponent;

    public function testSomeAspect() : void {
        component = new CustomComponent();
        // set some properties...

        component.addEventListener(FlexEvent.CREATION_COMPLETE, 
            addAsync(verifySomeAspect, 5000));

        component.height = 0;
        component.width = 0;
        Application.application.addChild(component);
    }

    public function verifySomeAspect(event:FlexEvent) : void {
        // Assert some things about component...
    }

    override public function tearDown() : void {
        try {
            if (component) {
                Application.application.removeChild(component);
                component = null;
            }
        } catch (e:Error) {
            // ok to ignore
        }
    }
基本上,您需要确保组件已经完全初始化,然后才能可靠地验证有关它的任何内容,而在Flex中,在将组件添加到显示列表后,这种情况会异步发生。因此,您需要设置一个回调(使用FlexUnit的addAsync函数),以便在发生回调时得到通知

最近,我只是手动调用运行时在必要位置为您调用的方法,所以现在我的测试看起来更像这样:

    import flexunit.framework.TestCase;

    public class CustomComponentTest extends TestCase {

        public function testSomeAspect() : void {
            var component:CustomComponent = new CustomComponent();
            component.initialize();
            // set some properties...
            component.validateProperties();

            // Assert some things about component...
        }
这很容易理解,但感觉上我有点作弊。第一种情况是将它猛击到当前的应用程序中(这将是单元测试运行程序shell应用程序),而后者不是一个“真实”的环境


我想知道其他人会如何处理这种情况?

我认为使用异步版本没有什么错。我同意第二个版本较短,但我不确定我认为它更容易理解。测试会做很多您通常不会做的事情,而第一个示例更真实地描述了如何在测试环境之外使用组件

另外,在第二种形式中,您必须确保您完全按照框架所做的做,错过一个步骤,并且您的测试不相关,并且每个测试都必须重复此代码。在我看来,最好在尽可能接近真实情况的情况下进行测试

你可以看看,他们让组件测试更具声明性:

public function testLogin():void {
    var passThroughData:Object = new Object();

    passThroughData.username = "myuser1";
    passThroughData.password = "somepsswd";

    var sequence:SequenceRunner = new SequenceRunner(this);

    sequence.addStep(new SequenceSetter(form.usernameTI, {text:passThroughData.username}));
    sequence.addStep(new SequenceWaiter(form.usernameTI, FlexEvent.VALUE_COMMIT, 100));

    sequence.addStep(new SequenceSetter(form.passwordTI, {text:passThroughData.password}));
    sequence.addStep(new SequenceWaiter(form.passwordTI, FlexEvent.VALUE_COMMIT, 100));

    sequence.addStep(new SequenceEventDispatcher(form.loginBtn, new MouseEvent("click", true, false)));
    sequence.addStep(new SequenceWaiter(form, "loginRequested", 100));

    sequence.addAssertHandler(handleLoginEvent, passThroughData);

    sequence.run();
}

(来自wiki的示例,)。

我认为使用异步版本没有什么错。我同意第二个版本较短,但我不确定我认为它更容易理解。测试会做很多您通常不会做的事情,而第一个示例更真实地描述了如何在测试环境之外使用组件

另外,在第二种形式中,您必须确保您完全按照框架所做的做,错过一个步骤,并且您的测试不相关,并且每个测试都必须重复此代码。在我看来,最好在尽可能接近真实情况的情况下进行测试

你可以看看,他们让组件测试更具声明性:

public function testLogin():void {
    var passThroughData:Object = new Object();

    passThroughData.username = "myuser1";
    passThroughData.password = "somepsswd";

    var sequence:SequenceRunner = new SequenceRunner(this);

    sequence.addStep(new SequenceSetter(form.usernameTI, {text:passThroughData.username}));
    sequence.addStep(new SequenceWaiter(form.usernameTI, FlexEvent.VALUE_COMMIT, 100));

    sequence.addStep(new SequenceSetter(form.passwordTI, {text:passThroughData.password}));
    sequence.addStep(new SequenceWaiter(form.passwordTI, FlexEvent.VALUE_COMMIT, 100));

    sequence.addStep(new SequenceEventDispatcher(form.loginBtn, new MouseEvent("click", true, false)));
    sequence.addStep(new SequenceWaiter(form, "loginRequested", 100));

    sequence.addAssertHandler(handleLoginEvent, passThroughData);

    sequence.run();
}
(来自wiki的示例,)