javascript - 如何使用 Express 且仅使用 JEST 来测试 REST API?

标签 javascript node.js unit-testing express jestjs

我可以仅使用 JEST 来测试 express 中的其余 API 端点吗?我搜索了几篇文章,也看到了 stackoverflow 的一些问题,看看我该如何做到这一点。但问题是在 express 中进行测试时,大多数人都使用 mocha/chaisupertest。但我想在测试中只使用 JEST。这可能吗?

这是我到目前为止想要实现此测试的代码:

index.js

const express = require('express');
const app = express();

app.post('/insert', function (req, res, next) {

    const values = req.body; //name, roll

      pool.query(`INSERT INTO student SET ?`, [values], (err, result) => {

        if (err){
          let err = new Error('Not Connected');
          next(err);
      } else {
          res.status(201).json({ msg: `added ${result.insertId}`});
          console.log(result);
        }

      });

});

到目前为止我尝试过的是: index.test.js:

const express = require('express');
const app = express();

app.use('../routes');

test('Test POST, Success Scenario', async () => {
    const response = await app.post('/insert')({
        const values //dummy values will be insert here
    });

    expect(response.statusCode).toBe(200);

});

我知道我的测试代码不正确,它只是一个伪代码,我实际上很困惑如何到达这里的终点

最佳答案

这是用于测试 Nodejs Web 框架 express REST API 仅使用 JEST 的单元测试解决方案:

index.js:

const express = require('express');
const { Pool } = require('pg');

const app = express();
const pool = new Pool();

app.post('/insert', (req, res, next) => {
  const values = req.body;

  pool.query(`INSERT INTO student SET ?`, [values], (err, result) => {
    if (err) {
      err = new Error('Not Connected');
      next(err);
    } else {
      res.status(201).json({ msg: `added ${result.insertId}` });
      console.log(result);
    }
  });
});

index.spec.js:

const routes = {};
jest.mock('express', () => {
  const mExpress = {
    post: jest.fn((path, controller) => {
      routes[path] = controller;
    })
  };
  return jest.fn(() => mExpress);
});

let queryCallback;
jest.mock('pg', () => {
  const mpool = {
    query: jest.fn((query, values, callback) => {
      queryCallback = callback;
    })
  };
  const mPool = jest.fn(() => mpool);
  return { Pool: mPool };
});

require('./index');
const express = require('express');
const { Pool } = require('pg');
const app = express();
const pool = new Pool();

describe('insert', () => {
  afterEach(() => {
    jest.restoreAllMocks();
  });
  test('should insert data correctly', done => {
    const logSpy = jest.spyOn(console, 'log');
    expect(app.post).toBeCalledWith('/insert', expect.any(Function));
    const mReq = { body: 1 };
    const mRes = { status: jest.fn().mockReturnThis(), json: jest.fn().mockReturnThis() };
    routes['/insert'](mReq, mRes);
    expect(pool.query).toBeCalledWith('INSERT INTO student SET ?', [1], expect.any(Function));
    const mResult = { insertId: 1 };
    queryCallback(null, mResult);
    expect(mRes.status).toBeCalledWith(201);
    expect(mRes.status().json).toBeCalledWith({ msg: 'added 1' });
    expect(logSpy).toBeCalledWith(mResult);
    done();
  });

  test('should call error handler middleware', () => {
    expect(app.post).toBeCalledWith('/insert', expect.any(Function));
    const mReq = { body: 1 };
    const mRes = { status: jest.fn().mockReturnThis(), json: jest.fn().mockReturnThis() };
    const mNext = jest.fn();
    routes['/insert'](mReq, mRes, mNext);
    expect(pool.query).toBeCalledWith('INSERT INTO student SET ?', [1], expect.any(Function));
    const mError = new Error('network error');
    queryCallback(mError, null);
    expect(mNext).toBeCalledWith(new Error('Not Connected'));
  });
});

100%覆盖率的单元测试结果:

 PASS  src/stackoverflow/56635460/index.spec.js (7.391s)
  insert
    ✓ should insert data correctly (15ms)
    ✓ should call error handler middleware (1ms)

  console.log node_modules/jest-mock/build/index.js:860
    { insertId: 1 }

----------|----------|----------|----------|----------|-------------------|
File      |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
----------|----------|----------|----------|----------|-------------------|
All files |      100 |      100 |      100 |      100 |                   |
 index.js |      100 |      100 |      100 |      100 |                   |
----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        8.571s

源代码:https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/56635460

关于javascript - 如何使用 Express 且仅使用 JEST 来测试 REST API?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56635460/

相关文章:

javascript - Node JS 异步/等待 Controller 问题

javascript - 我怎样才能像这样为 Angular Controller 和服务编写 Jasmine 测试?

javascript - 在不中断调整大小的情况下重置 jquery.resizable 元素的 "style"属性?

mysql - 使用 forEach() 和 Node.js 插入数据

javascript - 无法弄清楚我的 Javascript 程序的控制流程

javascript - 我正在开发的 Express/Socket.io 应用程序中的奇怪 JavaScript

unit-testing - 打开 NUnit 的卷影复制时,如何将资源(任何内容)文件复制到输出文件夹?

angular - ngx-translate:在单元测试中翻译字符串

javascript - JS Regex 最后两位数字匹配前两位数字

javascript - 我想单击一个元素来切换在完全不相关的元素上引用的类