Как я могу утверждать, что экспресс `res.status (200) .send ({hello: 'world'})` фактически отправил 200 с правильными данными? - PullRequest
0 голосов
/ 27 февраля 2019

Я хочу узнать, как правильно выполнить модульное тестирование экспресс-конечной точки, в частности только кода обработчика, и подтвердить правильное состояние и данные в ответе.

Я хочу сделать это БЕЗ supertest, поскольку у меня есть вспомогательная библиотека с кучей функций промежуточного программного обеспечения, и я хочу протестировать их изолированно.

Для такого простого приложения, как это

'use strict'

const express = require('express')
const app = express()
const helloWorld = require('./helloWorld')

app.get('/', helloWorld)

app.listen(5000, () => console.log('we\'re up!'))

С простой функцией-обработчиком, такой какэто

'use strict'

function helloWorld (req, res, next) {
  const data = {
    hello: 'world'
  }
  res.status(200).send(data)
}

module.exports = helloWorld

У меня есть этот тест в процессе создания

'use strict'
const helloWorld = require('./helloWorld')

describe('#helloWorld', () => {
  it('should return 200', () => {
    const req = {

    }

    const res = {
      status: function (code) {
        this.statusCode = code
        return this
      },
      send: function () {
        return this
      }
    }

    const next = () => {}

    helloWorld(req, res, next)
    // TODO: How to assert status was 200 and data sent was { hello: 'world' }?
  })
})

Как я могу подтвердить статус 200 и данные { hello: 'world' }?

Обновление Это работает, но я не знаю, если это ужасная идея.

Обновлен тест

'use strict'

const { expect } = require('chai')
const helloWorld = require('./helloWorld')

describe('#helloWorld', () => {
  it('should return 200', () => {
    const req = {

    }

    const res = {
      _status: null,
      _json: null,
      status: function (code) {
        this._status = code
        return this
      },
      send: function (json) {
        this._json = json
        return this
      }
    }

    const next = () => {}

    helloWorld(req, res, next)
    expect(res._status).to.equal(200)
    expect(res._json.hello).to.equal('world')
  })
})

Ответы [ 2 ]

0 голосов
/ 27 февраля 2019

Вам нужно принести библиотеку насмешек / заглушек (лично я склонен использовать Sinon ) и смоделировать объект res, например,

// Setup stubs
const req = {};
const res = {
   status() {},
   send() {}
};
const next = () => {}
// Setup mock
const resMock = sinon.mock(res);
resMock.expects('status').once().withArgs(200);
resMock.expects('send').once().withArgs({ hello: 'world' });
// Invoke code with mock
helloWorld(req, resMock, next);
// Assert expectations
resMock.verify();

Вы также можете использовать заглушки илишпионы, для нескольких утверждений функций, хотя я считаю, что макеты лучше настраивать.

Тот же пример использования шпионов вместо насмешек

// Setup stubs
const req = {};
const res = {
  status() {},
  send() {}
};
const next = () => {};
// Setup spies
const statusSpy = sinon.spy(res, 'status');
const sendSpy = sinon.spy(res, 'send');
// Invoke code
helloWorld(req, res, next);
// Assert calls 
expect(statusSpy.calledOnceWith(200)).to.be.true;
expect(sendSpy.calledWithMatch({ hello: 'world' })).to.be.true;

Если бы это было общей тенденцией во многих тестах, то вы могли бынастроить как

const req = {};
const res = {
  status() {},
  send() {}
};
const next = () => {};
...
before(() => {
  // Setup spies once for test suite
  sinon.spy(res, 'status');
  sinon.spy(res, 'send');
})

it('should return 200', () => {
  helloWorld(res, res, next);
  expect(res.status.calledOnceWith(200)).to.be.true;
  expect(res.send.calledWithMatch({ hello: 'world' })).to.be.true;
})

afterEach(() => {
  // reset spies after each test
  res.status.resetHistory();
  res.send.resetHistory();
})
0 голосов
/ 27 февраля 2019

Поскольку res.status() и res.send() на самом деле вызывают методы узла более низкого уровня. Js http, на самом деле встроенное тестирование не намного больше, чем здесь.Эти экспресс-методы в течение многих лет проверялись в нескольких крупных производственных средах крупными и малыми компаниями, поэтому вы можете быть уверены, что они выполнят свою работу.

Более полезным тестом может быть проверка того, что вашсервер отвечает с правильными ответами полностью.Что вы можете сделать, это создать отдельный файл test-server.js и использовать библиотеку request, чтобы выполнить несколько проверок на вашем сервере через localhost:port.Это имитирует взаимодействие клиента с вашим сервером.

const request = require('request');
const assert = require('assert');

// Example test
request('http://localhost:8080', (err, res, body) => {

  // Run your tests here
  assert.strictEqual(body.hello, 'world');
  assert.strictEqual(res.statusCode, 200);
  // .. etc
});

Затем вы можете запускать файл test-server.js каждый раз, когда вносите изменения в свой сервер для его проверки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...