javascript - 如何使用 Mocha、Chai 和 Sinon 正确测试 Express Controller 方法

标签 javascript express ecmascript-6 sinon sinon-chai

我刚开始使用 Sinon。我编写了以下测试,但它失败了,因为 res.status 总是返回未调用的状态。

import chai from 'chai';
import 'chai/register-should';
import sinon from 'sinon';
import sinonChai from 'sinon-chai';
import { db } from '../../models';
import * as loginController from '../../controllers/login';

chai.use(sinonChai);

describe('Login controller', () => {

  describe('post function', () => {
    let findOne, req, status, send, res;

    beforeEach(() => {
      findOne = sinon.stub(db.User, 'findOne');
      findOne.resolves(null);
      req = { body: { email: 'test@test.com', password: 'testpassword' }};
      status = sinon.stub();
      send = sinon.spy();
      res = { send: send, status: status };
      status.returns(res);
      loginController.post(req, res);
    });
    afterEach(() => {
      findOne.restore();
    });
    it('should return a 401 status for an invalid email', (done) => {
      res.status.should.be.calledWith(401);
      findOne.restore();
      done();
    });

  });
});

现在 Controller 中的方法非常简单。它首先使用 sequelize findOne 方法。如果它没有找到匹配的电子邮件,它应该抛出 401。这是它的样子:

export function post(req,res) {
  const email = req.body.email;
  const password = req.body.password;

  db.User.findOne({
    where: {email: email}
  }).then(user => {
    if (user) {
      // Other stuff happens here
    } else {
      res.status(401).send('That email address does not exist in our system.');
    }
  }).catch((error) => {
    res.status(500).send(error.message);
  });
}

当我运行测试时,它确实到达了应该返回状态的 else 语句,但是测试失败了,当我检查日志时,它说 res.status 不是曾经打电话过。

最佳答案

这里的问题是规范是同步的,没有考虑到 promise 。

出于可测试性原因返回 promise 是有意义的:

export function post(req,res) {
  ...
  return db.User.findOne(...)
  ...
}

如果路由处理程序是 async 函数,这可以很自然地完成。

由于 Mocha 支持 promises,规范也可以使用 async 函数代替 done 回调:

it('should return a 401 status for an invalid email', async () => {
  const handlerResult = loginController.post(req, res);
  expect(handlerResult).to.be.a('promise');

  await handlerResult;
  res.status.should.be.calledWith(401);
});

关于javascript - 如何使用 Mocha、Chai 和 Sinon 正确测试 Express Controller 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47415861/

相关文章:

javascript - 如何点击网站中没有 ID 或名称的登录图像?

node.js - node.js 中 Mocha 的代码覆盖率

node.js - 在 NodeJs 中处理 Mongodb 全局连接的最佳方法是什么

Javascript 合并对象数组中的重复项

javascript - 在 JavaScript 中调用 getter 函数及其名称?

javascript - 如何从 Android 应用程序对 Microsoft Azure 数据库执行请求

javascript - 查找字符串中 src 的值

javascript - 如何根据此 JSON 中的不同已知属性返回正确的 ID

javascript - Express.js、Passport.js 和 SockJS : How to attach user socket to deserializeUser

javascript - Javascript 中的 Object.__proto__.__proto__ 对象是否有通用术语/名称?