简体   繁体   English

如何使用Mocha,Chai和Sinon正确测试Express控制器方法

[英]How to properly test an Express controller method with Mocha, Chai, and Sinon

I'm pretty new to using Sinon. 我对使用Sinon非常陌生。 I have the following test I've written, and it fails because res.status always comes back as not called. 我已经编写了以下测试,但测试失败,因为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();
    });

  });
});

The method in the controller right now is pretty simple. 现在控制器中的方法非常简单。 It uses a sequelize findOne method first. 它首先使用一个sequelize findOne方法。 If it doesn't find a matching email it should throw a 401. Here's what that looks like: 如果找不到匹配的电子邮件,则会抛出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);
  });
}

When I run the test it does get to the else statement where it should be returning the status, but the test fails and when I check the log it says that the res.status wasn't ever called. 当我运行测试时,它确实到达了应返回状态的else语句,但是测试失败,并且当我检查日志时,它说从未调用过res.status

The problem here is that the spec is synchronous and doesn't take a promise into account. 这里的问题是规范是同步的,没有考虑到承诺。

It makes sense to return a promise for testability reasons: 出于可测试性的原因,返回承诺是有意义的:

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

This can be naturally done if route handler is async function. 如果路由处理程序是async函数,则可以自然完成此操作。

Since Mocha supports promises, the specs can use async functions instead of done callback as well: 由于Mocha支持Promise,因此规范可以使用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);
});

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

相关问题 如何使用 mocha、chai 和 sinon 模拟和测试闭包 - How to mock, and test, closures with mocha, chai and sinon 如何使用vanillajs和nodejs在Mocha / Chai / Sinon中测试addEventListener? - How to test addEventListener in Mocha/Chai/Sinon with vanillajs and nodejs? 模拟和测试Mocha,Chai和Sinon的按键事件? - Simulate and test a keypress event with Mocha, Chai, Sinon? 如何测试参数化方法是否会抛出chai和mocha? - How to test if parameterized method throws chai and mocha? 如何在 Chai 中模拟或存根 'instanceof' | 诗浓 | 摩卡 - How to mock or stub 'instanceof' in Chai | Sinon | Mocha 如果变量具有反应组件作为值,我如何使用 mocha/chai/sinon 进行单元测试? - How do i unit test using mocha/chai/sinon if a variable has a react component as value? 如何使用 mocha/sinon/chai 正确测试异步 stream 错误事件处理? - How do I correctly test asynchronous stream error event handling with mocha/sinon/chai? 如何测试使用Mocha,Sinn和Chai返回的函数? - How do I test a function which returns a function using Mocha, Sinon, and Chai? 确保在此测试中调用done()回调(Mocha,Chai,Sinon) - Ensure the done() callback is being called in this test (Mocha, Chai, Sinon) 为浏览器调整大小事件编写测试。 PhantomJS,摩卡,柴和诗乃 - Writing a test for a browser resize event. PhantomJS, Mocha, Chai & Sinon
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM