为了账号安全,请及时绑定邮箱和手机立即绑定

如何使用 Jest 在这种情况下测试 Express router catch 分支?

如何使用 Jest 在这种情况下测试 Express router catch 分支?

烙印99 2023-03-24 15:09:14
我有一个包含两条路线的文件。路线/index.jsconst express = require('express')const router = express.Router()router.get('', (req, res, next) => {  try {    res.status(200).render('../views/')  } catch (error) {    next(error)  }})router.get('*', (req, res, next) => {  try {    res.status(404).render('../views/not-found')  } catch (error) {    next(error)  }  })module.exports = router我想测试 catch 分支。一个明显的问题是我无法伪造 router.get 的回调所做的事情,因为那样我的测试将毫无意义,我会修改我想要测试的东西。我可以向这些特定路由发送超测请求,但我无法控制发生的情况。我想避免创建硬编码路由,这样我就可以检查下一个函数是否调用了中间件。如果我理解正确的话,如果我在 try 块中发生其他事情(比如数据库查询),那么我可以模拟它来抛出错误。但是我那里没有发生任何其他事情。这是我无法解决的问题:如果我模拟服务器的功能,那么我不会测试我已经拥有的东西,而是测试其他东西,所以这样做没有意义。也许我误解了事情是如何工作的,但据我所知,唯一的选择是以某种方式模拟 res.status 或 res.render 所做的事情(存根以便它们抛出错误),所以以某种方式模拟 Supertest 所做的事情,但我不知道该怎么做。任何帮助将不胜感激!
查看完整描述

1 回答

?
至尊宝的传说

TA贡献1789条经验 获得超10个赞

单元测试解决方案:


route.js:


const express = require('express');

const router = express.Router();


router.get('', (req, res, next) => {

  try {

    res.status(200).render('../views/');

  } catch (error) {

    next(error);

  }

});


router.get('*', (req, res, next) => {

  try {

    res.status(404).render('../views/not-found');

  } catch (error) {

    next(error);

  }

});


module.exports = router;

route.test.js:


describe('64051580', () => {

  afterEach(() => {

    jest.resetModules();

    jest.restoreAllMocks();

  });

  it('should render views', () => {

    const express = require('express');

    const mRouter = { get: jest.fn() };

    jest.spyOn(express, 'Router').mockImplementationOnce(() => mRouter);

    const mReq = {};

    const mRes = { status: jest.fn().mockReturnThis(), render: jest.fn() };

    const mNext = jest.fn();

    mRouter.get.mockImplementation((path, callback) => {

      if (path === '') {

        callback(mReq, mRes, mNext);

      }

    });

    require('./route');

    expect(mRes.status).toBeCalledWith(200);

    expect(mRes.render).toBeCalledWith('../views/');

  });


  it('should handle error', () => {

    const express = require('express');

    const mRouter = { get: jest.fn() };

    jest.spyOn(express, 'Router').mockImplementationOnce(() => mRouter);

    const mReq = {};

    const mErr = new Error('parse');

    const mRes = {

      status: jest.fn().mockReturnThis(),

      render: jest.fn().mockImplementationOnce(() => {

        throw mErr;

      }),

    };

    const mNext = jest.fn();

    mRouter.get.mockImplementation((path, callback) => {

      if (path === '') {

        callback(mReq, mRes, mNext);

      }

    });

    require('./route');

    expect(mNext).toBeCalledWith(mErr);

  });


  it('should render 404 not found view', () => {

    const express = require('express');

    const mRouter = { get: jest.fn() };

    jest.spyOn(express, 'Router').mockImplementationOnce(() => mRouter);

    const mReq = {};

    const mRes = { status: jest.fn().mockReturnThis(), render: jest.fn() };

    const mNext = jest.fn();

    mRouter.get.mockImplementation((path, callback) => {

      if (path === '*') {

        callback(mReq, mRes, mNext);

      }

    });

    require('./route');

    expect(mRes.status).toBeCalledWith(404);

    expect(mRes.render).toBeCalledWith('../views/not-found');

  });

});

带有覆盖率报告的单元测试结果:


 PASS  src/stackoverflow/64051580/route.test.js

  64051580

    ✓ should render views (656ms)

    ✓ should handle error (17ms)

    ✓ should render 404 not found view (16ms)


----------|----------|----------|----------|----------|-------------------|

File      |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |

----------|----------|----------|----------|----------|-------------------|

All files |    90.91 |      100 |      100 |    90.91 |                   |

 route.js |    90.91 |      100 |      100 |    90.91 |                16 |

----------|----------|----------|----------|----------|-------------------|

Test Suites: 1 passed, 1 total

Tests:       3 passed, 3 total

Snapshots:   0 total

Time:        4.28s, estimated 10s


查看完整回答
反对 回复 2023-03-24
  • 1 回答
  • 0 关注
  • 86 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信