我如何测试在快递中使用mocha / chai / superagent发送路由?

时间:2016-05-11 18:22:47

标签: node.js testing express mocha chai

{{1}}

我是测试的新手,我讨厌它......很多。我试图学习基础知识,这是我经历过的最令人沮丧的学习曲线。我已经查了几个小时的文档,但仍然无法弄清楚如何查看已经呈现的路线

1 个答案:

答案 0 :(得分:3)

我会采用另一种方式:而不是依赖于请求的输出,并将其与模板相匹配(除非您为每个模板添加某种标识符,否则这可能非常困难,这不会感觉到完全正确的,你可以利用Express的一些内部功能,特别是它如何呈现模板。

Express文档说明了以下内容(here):

  

符合Express的模板引擎(如Pug)导出名为__express(filePath, options, callback)的函数,该函数由res.render()函数调用以呈现模板代码。

您没有使用Pug,而是使用EJS,但同样的原则适用:ejs模块导出一个名为__express的函数,该函数将使用应呈现的模板的完整路径进行调用。这也恰好是你想要测试的东西!

现在问题变成了:“你如何测试ejs.__express()是否使用正确的模板名称进行调用?”。答:你可以间谍

我最喜欢的模块是Sinon,因此下面的示例将使用它。 Sinon非常善于监视现有的功能,或者如果你愿意,可以让他们做完全不同的事情。

作为一个例子,我将使用以下非常简单的Express应用程序:

// app.js
const express = require('express');
const app     = express();

app.get('/', (req, res) => {
  res.render('index.ejs', { foo : 'bar' });
});

module.exports = app;

我们想测试,在请求/时,是否会呈现模板index.ejs

我将使用supertest,而不是使用superagent,而是用于测试HTTP应用。

这是带注释的Mocha测试文件:

// Import the Express app (from the file above), which we'll be testing.
const app = require('./app');

// Import some other requirements.
const expect    = require('chai').expect;
const supertest = require('supertest');
const sinon     = require('sinon');

// Import the EJS library, because we need it to spy on.  
const ejs = require('ejs');

// Here's the actual test:
it('sends login page if we\'re logged out at /', function (done) {
  // We want to spy on calls made to `ejs.__express`. We use Sinon to
  // wrap that function with some magic, so we can check later on if
  // it got called, and if so, if it got called with the correct
  // template name.
  var spy = sinon.spy(ejs, '__express');

  // Use supertest to retrieve / and make sure that it returns a 200 status
  // (so we don't have to check for that ourselves)
  supertest(app)
    .get('/')
    .expect(200)
    .end((err, res) => {
      // Pass any errors to Mocha.
      if (err) return done(err);

      // Magic! See text below.
      expect(spy.calledWithMatch(/\/index\.ejs$/)).to.be.true;

      // Let Sinon restore the original `ejs.__express()` to its original state.
      spy.restore();

      // Tell Mocha that our test case is done.
      done();
    });
});

那么这就是什么魔法:

spy.calledWithMatch(/\/index\.ejs$/)

这意味着:“如果使用与正则表达式true匹配的第一个参数调用正在监视的函数(ejs.__express()),则返回\/index\.ejs$” EM>。这是你想要测试的。

我在这里使用正则表达式的原因是因为我很懒。因为第一个参数(上面引用中的filePath)将包含模板文件的完整路径,所以它可能会很长。如果需要,您可以直接测试它:

spy.calledWith(__dirname + '/views/index.ejs')

但是如果模板目录的位置发生了变化,那将会中断。所以,就像我说的那样,我很懒,而且我会使用正则表达式匹配。

使用supertestsinonchai等工具,测试实际上可以变得有趣(诚实!)。我不得不同意学习曲线相当陡峭,但也许这样一个带注释的例子可以帮助你更好地了解什么是可能的以及如何去做。