如何为读取package.json的子生成器设置yeoman测试

时间:2015-04-17 11:16:57

标签: javascript node.js mocha yeoman

我有一个使用package.json名称的子生成器。现在我想测试该函数并编写一个before(),它应该为测试创建一个虚拟的package.json。

问题是子生成器无法读取虚拟json文件。

测试文件:

before(function (done) {

  helpers.run(path.join( __dirname, '../addcomponent'))
  .inDir(path.join( __dirname, './tmp'), function(dir) {

    fs.copyTpl(
      path.join(__dirname, '../app/templates/_package.json'),
      dir + 'package.json',
      { ProjectName: 'foo' }
    );

    var test = fs.readJSON(dir + 'package.json');
    console.log('test: ' + test); // returns the object
    console.log('test.name: ' + test.name); // returns the correct name

  })
  .withArguments(['foo'])
  .withPrompts(prompts)
  .withOptions(options)
  .on('end', done);

});

但在我的子发电机中:

var memFs = require('mem-fs');
var editor = require('mem-fs-editor');
var store = memFs.create();
var fs = editor.create(store);

...

init: function() {
  this.pkg = this.fs.readJSON('package.json');
  console.log('this.pkg: ' + this.pkg); // returns undefined
}
// or
init: function() {
  this.on('ready', function() {
    this.pkg = this.fs.readJSON('package.json');
    console.log('this.pkg: ' + this.pkg); // returns undefined
  });
}
// or
anyOther: function() {
  this.pkg = this.fs.readJSON('package.json');
  console.log('this.pkg: ' + this.pkg); // returns undefined
}

可以在此处找到整个设置:https://travis-ci.org/markusfalk/generator-kickstart/builds/58892092

感谢您的帮助

1 个答案:

答案 0 :(得分:0)

编辑:我会将旧答案保留在下面,这可能与遇到此问题的大多数人有关,但不适合您。

mem-fs背后的想法是拥有内存存储。它不会自动将任何内容写入磁盘。因此,它将状态保持在mem-fs实例中。在这种情况下,您将创建自己的mem-fs实例,而yeoman则使用另一个实例。这意味着您编写的文件从未被Yeoman看到(并且从未写入磁盘)。

对于您来说,修复方法是使用提供的生成器实例作为ready事件的第一个参数。

helpers.run(path.join( __dirname, '../addcomponent'))
  .on('ready', function (generator) {
    generator.fs.write('file.txt', 'foo');
  });

另一种选择是使用node.js sync fs方法。 (fs.writeFileSync()等)


我的猜测是你在生成器构造函数中使用this.fs.readJSON()

在触发ready事件之前初始化构造函数。这意味着你在文件实际写入之前就已经读过了。

通常的解决方法是永远不要在构造函数内部读取。您可以延迟此步骤,直到initializing(或inDir()事件)回调运行的ready阶段。

作为旁注,您应该使用inTmpDir()而不是inDir()