【问题标题】:Test try-catch on Express API with mocha, chai, chai-http and sinon使用 mocha、chai、chai-http 和 sinon 在 Express API 上测试 try-catch
【发布时间】:2020-10-11 14:29:21
【问题描述】:

我有一个使用 Express 创建的 API 应用,在控制器上使用此功能

/** UserController.ts */ 
--------------------------

  public static get = async (req: Request, res: Response): Promise<void> => {
    try {
      const user = await UserModel.findById(<<id>>)
 
      if (user) {
        res.status(200).json(<I200Response>{ msg: 'user data', data: user })
      }
    } catch (e) {
      res.status(500).json(<I500Response>{ error: e.message })
    }
  }

我正在尝试使用 sinon 测试“catch block”的工作原理,但我不明白。这是我尝试过的数百个测试之一:

/** User.specs.ts */
---------------------

  it('Internal server error', async () => {
    const stubReq = chai.request(BASE)
    const stub = sinon.stub(stubReq, 'get').throws(new Error('stub: Internal server error'))

    const r = await request.get(API.info).set('Authorization', userToken)
    stub.reset()

    expect(r).to.have.status(500)
    return expect(r.body).to.have.property('error').that.is.equal('stub: Internal server error')
  })

但响应的状态为 200 并获取所需的数据。

有什么想法吗?

【问题讨论】:

    标签: express try-catch integration-testing sinon chai-http


    【解决方案1】:

    您应该使用sinon.js 存根带有被拒绝的承诺的UserModel.findById 方法。

    例如

    UserController.ts:

    import { Request, Response } from 'express';
    import { UserModel } from './UserModel';
    
    type I500Response = any;
    type I200Response = any;
    
    export class UserController {
      public static get = async (req: Request, res: Response): Promise<void> => {
        try {
          const user = await UserModel.findById(1);
    
          if (user) {
            res.status(200).json(<I200Response>{ msg: 'user data', data: user });
          }
        } catch (e) {
          res.status(500).json(<I500Response>{ error: e.message });
        }
      };
    }
    

    UserModel.ts:

    export class UserModel {
      public static findById(id: number) {
        return { id, name: 'real username' };
      }
    }
    

    app.ts:

    import express from 'express';
    import { UserController } from './UserController';
    
    const app = express();
    const port = 3000;
    app.get('/user/:id', UserController.get);
    
    export { app };
    

    app.test.ts:

    import chai, { expect } from 'chai';
    import chaiHttp from 'chai-http';
    import { app } from './app';
    import { UserModel } from './UserModel';
    import sinon from 'sinon';
    
    chai.use(chaiHttp);
    
    describe('62502383', () => {
      it('should pass', (done) => {
        const mError = new Error('stub: Internal server error');
        const findByIdStub = sinon.stub(UserModel, 'findById').rejects(mError);
        chai
          .request(app)
          .get('/user/1')
          .end((err, res) => {
            sinon.assert.calledWith(findByIdStub, 1);
            expect(res).to.have.status(500);
            expect(err).to.be.null;
            expect(res.body.error).to.be.equal('stub: Internal server error');
            done();
          });
      });
    });
    

    集成测试结果:

      62502383
        ✓ should pass
    
    
      1 passing (31ms)
    
    -------------------|---------|----------|---------|---------|-------------------
    File               | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
    -------------------|---------|----------|---------|---------|-------------------
    All files          |   82.35 |        0 |   66.67 |   81.25 |                   
     UserController.ts |   77.78 |        0 |     100 |      75 | 12-13             
     UserModel.ts      |      50 |      100 |       0 |      50 | 3                 
     app.ts            |     100 |      100 |     100 |     100 |                   
    -------------------|---------|----------|---------|---------|-------------------
    

    【讨论】:

    • 添加一个 sinon 沙箱它可以工作而不影响其余的测试。然而,这不是我要找的,因为虽然它会引发错误,但它没有执行 UserController.get 方法,因此 nyc 覆盖失败​​。
    猜你喜欢
    • 2015-12-01
    • 1970-01-01
    • 2015-11-06
    • 2018-04-08
    • 2015-06-02
    • 1970-01-01
    • 2023-04-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多