单元测试 编辑页面


英文原文:http://emberjs.com/guides/testing/unit/

单元测试用于测试代码的一个小片段,确保其功能正常。与集成测试不同,单元测试被限定在一个范围内,并且不需要Ember应用运行。

全局 vs 模块

过去如果没有作为一个全局变量加载整个Ember应用,要对应用进行测试非常困难。通过使用模块(CommonJSAMD等)来编写应用,可以只加载被测试的部分,而不用将其从全局的应用中抽出来测试。

单元测试助手

Ember-QUnit是Ember的缺省的单元测试助手套件。其可以作为其他测试框架助手的样板来使用。Ember-QUnit使用应用的resolver来查找并使用moduleFortest助手自动创建被测主体。

测试主体是一个特定测试将围绕其进行断言的一个简单对象的实例。通常测试主体有测试者手动创建。

本指南中的单元测试将采用Ember-QUnit来完成,不过其中的概念和例子可以非常容易的迁移至其他的框架。

可用的助手

通过加入Ember-QUnit,可以获取一系列测试助手。

  • moduleFor(fullName [, description [, callbacks]])

    • fullName: 单元测试全名。(例如:controller:applicationroute:index等。)
    • description: 模块描述。
    • callbacks: 完成附加需求的QUnit回调(setupteardown),可以通过回调来指定测试需要的其他单元)。
  • moduleForComponent(name [, description [, callbacks]])

    • name: 将被用于模板中得简短组件名。(例如:x-fooic-tabs等等。)
    • description: 模块描述。
    • callbacks: 完成附加需求的QUnit回调(setupteardown),可以通过回调来指定测试需要的其他单元)。
  • moduleForModel(fullName [, description [, callbacks]])

    • name: 在store操作中将使用的简短模型名。(例如:userassignmentGroup等。)
    • description: 模块描述。
    • callbacks: 完成附加需求的QUnit回调(setupteardown),可以通过回调来指定测试需要的其他单元)。
  • test

    • 与QUnit的test期望一样,其包含了用来创建测试主体的subject函数。 to create the test subject.
  • setResolver

  • 设置用来从应用容器中查找对象的resolver

设置单元测试

为了对Ember应用进行单元测试,首先需要让Ember知道其在测试模式。为实现这个目的,需要调用Ember.setupForTesting()

1
Ember.setupForTesting();

setupForTesting()函数的调用通知Ember关闭了其自动运行循环的执行。这样使得可以能够自己一定程度上控制运行循环流程。缺省的履行所有承诺和完成所有异步行为的行为被暂停,使得可以在一个已知的状态来作出断言。换句话说,如果已知运行visit到一个特定的URL,就可以肯定URL被访问并且也是唯一发生的行为。如果并没有采用这种方式,那么断言很可能会在异步行为发生之前就被执行了,以至于断言结果并不是可预知。

在一个基于模块的应用里,可以通过请求模块的导出来访问单元测试助手。然而,如果在测试一个全局的Ember应用,一样可以使用单元测试助手。作为导入ember-qunit模块的替代方案,需要通过emq.globalize()来使得单元测试变成全局的。

1
emq.globalize();

这就使得上述的助手变成了全局可用。

解析器

Ember解析器在对应用进行单元测试的时候扮演了一个非常重要的角色。其提供了一个基于名字查找的功能,例如route:index或者model:post

如果没有一个自定义的解析器,或者测试一个全局的Ember应用,解析器应该进行如下的设置:

确定使用应用的命名空间来替代下面一行代码中得App

1
setResolver(Ember.DefaultResolver.create({ namespace: App })

否则,需要获取自定义解析器,并将其传递给setResolver,就如(ES6示例)中一般:

1
2
3
import Resolver from './path/to/resolver';
import { setResolver } from 'ember-qunit';
setResolver(Resolver.create());