为sailsJS(或其他框架)创建单元测试的方法是什么

时间:2018-01-20 13:10:03

标签: javascript unit-testing mocking sails.js

在学习C#的过程中,我接受了测试驱动开发(这些似乎是相辅相成的)。但是在javascript中我很难为tdd找到一个好的工作流程。这主要是由于许多框架的组合,似乎考虑测试二等公民。

作为一个例子,考虑一个班级worker。该类具有一些作用于数据库的功能。那么我如何为这个类的功能编写单元测试呢?

在c#(以及C / JAVA系列的其余部分)中,我将以这样的方式编写此类,即构造函数将采用数据库连接参数。然后在测试运行期间,使用mock-database-connection对象而不是真实对象调用对象。因此没有修改源。 在python中可以使用类似的方法,但是除了向构造函数提供模拟对象以处理HAS_A依赖项之外,我们还可以使用依赖注入来模拟IS_A依赖项。

<小时/> 现在在javascript中使用它,特别是sailsJS(尽管在sencha和其他框架中也会出现类似的问题)。似乎代码与库/框架紧密耦合,我无法创建手动存根/模拟? - 除了实际使用预运行任务来修改source / config.js?

在sails中,一个对象(比如worker,一个控制器)必须驻留在一个特定的文件夹中才能工作,它会自动“连接”到数据库,而不提供任何数据库对象的概念。 (因此阻止我实际提供我自己的对象)。

假设我有一个带有“学生”表的数据库,那么控制器看起来就像(Students中定义的模型api/models

const request = require('request');
module.exports = {
  updateData: function (req, res) {
    let idx = params.jobNumber;
    Students.find({Nr:idx})
      .exec(function (err, result) {
         //....
      });
  },
};

那么如何将上述函数加载到(mocha)测试中呢?我将如何解耦数据库(由sails隐式使用)以便我可以模拟功能? - 我该怎么做呢?

我当然不希望进行集成测试,所以我不应该建立一个“开发数据库”,因为我不想测试连接,我希望测试一下控制器的功能。

3 个答案:

答案 0 :(得分:0)

Sails Unit Test在以下博客中有完美的解释。

https://www.packtpub.com/books/content/how-add-unit-tests-sails-framework-application

请参阅。

答案 1 :(得分:0)

在文档中,它们提供了一个很好的快速示例,说明如何使用Mocha设置测试:https://sailsjs.com/documentation/concepts/testing

bootstrap.test.js文件中,他们正在做的就是使用Sails升级和降低应用程序,这样您的应用程序就可以访问控制器/模型等。在其测试环境中。他们还展示了如何测试单个控制器,这实际上只是发出命令来触发端点以触发控制器的操作。为避免测试请求的整个生命周期,您只需要在*.test.js文件中包含控制器文件并测试任何导出的操作。但请记住,Sails会构建传递给控制器​​的请求和响应对象。因此,如果您想要所有正确的数据并使这些对象有效,最好让Sails处理它,并且您只向端点发出请求,除非您知道完全如何构建请求和响应对象。但是,这就是框架的重点:您可以按预期使用它,并对其进行测试。您没有使用它的版本如何工作。 TDD适用于所有语言和框架,您只需将其融入您的技术中。

如果您不想为测试环境使用数据库,可以通过在sails-disk下为测试环境创建环境文件并强制该环境,告诉它使用config/env/适配器使用sails-disk

例如......

config/env/test.js - &gt;测试环境文件

module.exports = {

  models: {
    connection: 'localDiskDb',
    migrate: 'drop',
  },

  port: 1337,

  host: '127.0.0.1',

};

config/connections.js下面的connections对象(如果还没有)......

localDiskDb: {
  adapter: 'sails-disk'
},

最后,我们需要告诉它在运行测试时使用该环境。修改test/bootstrap.test.js,如下所示......

var sails = require('sails');

before(function(done) {

  // Increase the Mocha timeout so that Sails has enough time to lift.
  this.timeout(10000);
  // Set environment to testing
  process.env.NODE_ENV = 'test';

  sails.lift({
    // configuration for testing purposes
  }, function(err) {
    if (err) {
      return done(err);
    }

    //...

    done(err, sails);
  });
});

after(function(done) {
  // here you can clear fixtures, etc.

  // This will "refresh" the memory store so you
  // have a clean test datastore every time you run tests
  sails.once('hook:orm:reloaded', () => {
    sails.lower((err) => {
      done();

      if (err) {
        process.exit(1);
      } else {
        process.exit(0);
      }
    });
  });

  sails.emit('hook:orm:reload');
});

答案 2 :(得分:0)

以“答案”格式添加杰森的建议,以便其他人可以更轻松地找到它。

sails-mock-models允许基于sinon对Sails模型查询进行简单的模拟

嘲笑任何标准查询方法(即“查找”,“计数”,“更新”),它们将被调用而不会产生副作用。

我还没有尝试过(只是找到了这个问题),但是如果有任何问题,我会进行编辑。