继续阅读以了解有关Yeoman添加的测试助手的更多信息,以减轻对Generator进行单元测试的痛苦。
以下示例假定您在BDD模式下使用Mocha。 全局概念应轻松应用于您选择的单元测试框架。
9.1 组织测试
很重要的一点是,要保持测试简单且易于编辑。
通常,组织测试的最佳方法是:
- 将每个Generator和子Generator分离到其自己的describe块中。
- 为Generator接受的每个选项添加一个describe块。
- 对每个声明(或相关声明)使用it块。
在代码中,您应该以类似于以下的结构结束:
describe('backbone:app', function () {
it('generates a project with require.js', function () {
// assert the file exist
// assert the file uses AMD definition
});
it('generates a project with webpack');
});
9.2 测试助手
Yeoman提供测试助手方法。 它们包含在yeoman测试包中。
var helpers = require('yeoman-test');
对Generator进行单元测试时,最有用的方法是helpers.run()。 此方法将返回一个RunContext实例,您可以在该实例上调用方法来设置目录,模拟提示,模拟参数等。
var path = require('path');
it('generate a project', function () {
// The object returned acts like a promise, so return it to wait until the process is done
return helpers.run(path.join(__dirname, '../app'))
.withOptions({ foo: 'bar' }) // Mock options passed in
.withArguments(['name-x']) // Mock the arguments
.withPrompts({ coffee: false }) // Mock the prompt answers
.withLocalConfig({ lang: 'en' }) // Mock the local config
.then(function() {
// assert something about the generator
});
})
为Generator构建一个测试方案,与目标目录中的现有内容一起运行。 在这种情况下,使用回调函数来调用inTmpDir(),如下所示:
var path = require('path');
var fs = require('fs-extra');
helpers.run(path.join(__dirname, '../app'))
.inTmpDir(function (dir) {
// `dir` is the path to the new temporary directory
fs.copySync(path.join(__dirname, '../templates/common'), dir)
})
.withPrompts({ coffee: false })
.then(function () {
assert.file('common/file.txt');
});
也可以在回调中执行异步任务:
var path = require('path');
var fs = require('fs-extra');
helpers.run(path.join(__dirname, '../app'))
.inTmpDir(function (dir) {
var done = this.async(); // `this` is the RunContext object.
fs.copy(path.join(__dirname, '../templates/common'), dir, done);
})
.withPrompts({ coffee: false });
执行Promise将使用运行Generator的目录进行解析。如果要使用运行生成器的临时目录,这将很有用:
helpers.run(path.join(__dirname, '../app'))
.inTmpDir(function (dir) {
var done = this.async(); // `this` is the RunContext object.
fs.copy(path.join(__dirname, '../templates/common'), dir, done);
})
.withPrompts({ coffee: false })
.then(function (dir) {
// assert something about the stuff in `dir`
});
如果生成器调用composeWith(),则可能要模拟那些依赖的生成器。 使用#withGenerators(),传入使用#createDummyGenerator() 作为第一项,并使用模拟生成器的命名空间作为第二项的数组的数组:
var deps = [
[helpers.createDummyGenerator(), 'karma:app']
];
return helpers.run(path.join(__dirname, '../app')).withGenerators(deps);
如果不使用Promise,则可以使用发出的“ready”,“error”和“end”事件:
helpers.run(path.join(__dirname, '../app'))
.on('error', function (error) {
console.log('Oh Noes!', error);
})
.on('ready', function (generator) {
// This is called right before `generator.run()` is called
})
.on('end', done);
也可以运行生成器,将其导入为模块。 如果编译了Generator的源代码,这将很有用。
需要提供以下设置:
resolved
: 到Generator的路径,如:../src/app/index.js
namespace
: Generator的命名空间,如:mygenerator:app
var MyGenerator = require('../src/app');
helpers.run(MyGenerator, {
resolved: require.resolve(__dirname, '../src/app/index.js'),
namespace: 'mygenerator:app'
});
9.3 断言
Yeoman使用Generator相关的断言助手扩展了本地断言模块。 可以在yeoman-assert存储库中看到断言助手的完整列表。
需要引入yeoman-assert
var assert = require('yeoman-assert');
断言文件存在
assert.file(['Gruntfile.js', 'app/router.js', 'app/views/main.js']);
assert.noFile() 断言与assert.file() 相反。
断言一个文件内容
assert.fileContent('controllers/user.js', /App\.UserController = Ember\.ObjectController\.extend/);
assert.noFileContent断言与assert.fileContent() 相反。
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 |