FlexUnit组件测试模式:使用addAsync还是手动初始化?
时间:2020-03-05 18:45:14 来源:igfitidea点击:
我们在这里使用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... }
这很容易理解,但是有点像我在任一种方式都在作弊。第一种情况是将其猛击到当前应用程序中(该应用程序将是单元测试运行器外壳应用程序),而后者不是一个"真实的"环境。
我想知道其他人将如何处理这种情况?
解决方案
回答
我认为使用异步版本没有错。我可以同意第二个版本较短,但是我不确定我认为更容易理解。该测试完成了许多我们通常不会做的事情,而第一个示例更适合我们在测试环境之外使用组件的方式。
同样,在第二种形式中,我们必须确保完全按照框架的方式进行操作,错过了一步,并且测试不相关,并且每个测试都必须重复此代码。在我看来,最好在尽可能接近真实事物的情况下进行测试。
我们可以看一下dpUint的序列,它们使组件测试更具声明性:
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(); }
(例如,来自dpUint Wiki的示例,请参见此处以获取更多信息)。