繁体   English   中英

来自服务的控制器解析承诺的Mocha单元测试

[英]Mocha Unit Testing of Controller resolving promise coming from services

我有控制器:

 function(req, res) { // Use the Domain model to find all domain CIO.find(function(err, CIOs) { if (err) { response = responseFormat.create(false, "Error getting CIOs", err, {}); res.status(400).json(response); } else { var metrics = { "count": CIOs.length }; // .then means it will wait for it to finish, then let you have the result var promises = []; for (i in CIOs) { promises.push(Analysis.structureMetrics(CIOs[i].toObject())) } var output = [] var errors = [] Q.allSettled(promises) .then(function(results) { for (i in results) { if (results[i].state === "rejected") { console.log(results[i]) errors.push(results[i].reason.errors) output.push(results[i].reason) } else { output.push(results[i].value) } } }).then(function() { response = responseFormat.create(true, "List of all CIOs", output, metrics, errors); res.status(200).json(response); }) } }); }; 

和cio.test文件:

 describe('/cio', function() { describe('GET', function() { //this.timeout(30000); before(function() { }); it('should return response', function(done) { var response = http_mocks.createResponse({eventEmitter: require('events').EventEmitter}) var request = http_mocks.createRequest({ method: 'GET', url: '/cio', }) //var data = JSON.parse( response._getData() ); response.on('end', function() { response.statusCode.should.be.equal(400); done(); }) cioCtrl.getCIOs(request, response); }); }); }); 

出现错误

错误:超时超过10000ms。 确保在此测试中调用了done()回调

1>我已经尝试过增加时间,但是没有用。

2>我发现的是response.('end', function(){})没有被调用,但是不确定为什么

任何帮助,将不胜感激。 谢谢!

单元测试的一个很好的方法是使用依赖注入

为此,您的控制器文件应如下所示:

module.exports = class MyController {
  constructor(CIO) {
    this._CIO = CIO;
    this.handler = this.handler.bind(this);
  }

  handler(req, res) {
    // your code here using this._CIO
  }
};

在主文件中,您将创建控制器实例:

const MyController = require('./controllers/my-controller');

// require your CIO, or create instance...
const CIO = require('./CIO');

const myController = new MyController(CIO);

然后,您只需将控制器实例或它的处理函数传递到将使用它的地方。

使用这种方法可以使您进行良好的测试。 假设您的“ it”看起来像这样:

it('should work', function(done) {
  const fakeCIO = { 
    find: function() {
      done();
    }
  };
  const myController = new MyController(fakeCIO);
  myController.handler();
});

测试技术之间的基本区别:

  • 单元测试-您测试一个单元,它如何调用函数,进行赋值,返回值
  • 集成测试-将数据库添加到以前的测试中,并检查数据库的存储/删除/更新方式
  • 端到端测试-您将API端点添加到先前的集成测试中,并检查整个流程的工作方式

更新:
使用异步/等待方法,您将能够使用控制器测试更多的东西。 假设以如下方式修改它:

async function(req, res) {
  try {
    const CIOs = await CIO.find();
    const metrics = {
      "count": CIOs.length
    };
    const promises = CIOs.map(el => Analysis.structureMetrics(el.toObject());

    for(const promise of promises) {
      const result = await promise();
      // do whatever you need with results
    }

  } catch(err) {
    const response = responseFormat.create(false, "Error getting CIOs", err, {});
    res.status(400).json(response);
  }

使用这种方法,在单元测试期间,您还可以测试您的控制器调用了以下方法:

  • responseFormat.create
  • Analysis.structureMetrics
  • 状态
  • res.json
  • 要执行的测试catch分支

所有这些都是使用伪造的对象完成的。 并且确保使用OOP不是强制性的,这只是一个习惯问题,您可以使用函数样式(例如,使用closures )进行相同的操作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM