如果使用 chai-spies / Mocha / Test 调用,如何测试函数(节点模块)

How to test a function (node module) if it's called with chai-spies / Mocha / Test

我想测试是否正在使用 chai-spies 调用函数。

这是我要测试的class

index.js

const express = require('express');
const router = express.Router();
const request = require('request');

router.post('/login',(req,res) => {

    const {username, password} = req.body;
    let login= {};
    login.username= username;
    login.password= password;
    try{

        request.post({    // <---- this is the function I want to test if its called
            header: {'Content-Type': 'application/json-patch+json', 'accept ': 'application/json'},
            url: ' https://exmple',
            json: login
        }, function (error, response, body) {
            // implementation
        });
        } catch (error) {
    console.log(error);
}
});
module.exports = router;

以下是我尝试编写的测试文件

index.test.js

const route = require ("../routes/index");
const spy = chai.spy.on(route,'request');
const request = require("supertest");
const express = require("express");
const bodyParser = require('body-parser');
const chai = require('chai');
let spies = require('chai-spies');
chai.use(spies);
const expect = chai.expect;

//create app without credentials
let app = express();
    app.use(express.urlencoded({ extended: false }));
    app.set('view engine', 'ejs');
    app.use(bodyParser.json());
    app.use(bodyParser.urlencoded({extended: true}));
    app.use(route);

describe("Testing the POST /login route", () => {

let spy = chai.spy.on(route,'request'); // I tried to mock the function here with chai spies.

 it('should make a request to backend server when form is filled, but with wrong credentials', (done) => 
 {
        request(app)
            .post('/login')
            .set('Accept', 'application/json')
            .send({username:"test",password:"test"})
            .end(function (err,res) {   
                expect(spy).to.have.been.called.once;
                done();
            });
    });
});

如你所见,我试图用 chai spies 模拟请求函数 let spy = chai.spy.on(route,'request');

但是当我 运行 代码时它确实识别模拟函数并且 return

Uncaught AssertionError: expected { Spy 'object.request' } to have been called once but got 0
    + expected - actual

    -0
    +1

如果请求函数被调用,我如何测试它。该请求实际上是一个节点模块,用于在另一台后端服务器上进行http调用。

感谢您的帮助。

您没有正确模拟 request.post 方法。此外,您应该实现 /login 路由的控制器,这意味着您需要使用 res.send()res.json()res.end() 向客户端发送一些数据。否则,超测客户端得不到响应,会使测试用例超时。

这是一个例子:

index.js:

const express = require('express');
const router = express.Router();
const request = require('request');

router.post('/login', (req, res) => {
  const { username, password } = req.body;
  let login = {};
  login.username = username;
  login.password = password;

  try {
    request.post(
      {
        header: { 'Content-Type': 'application/json-patch+json', 'accept ': 'application/json' },
        url: ' https://exmple',
        json: login,
      },
      function(error, response, body) {
        res.send('implementation');
      },
    );
  } catch (error) {
    console.log(error);
  }
});
module.exports = router;

index.test.js:

const route = require('./');
const request = require('request');
const supertest = require('supertest');
const express = require('express');
const bodyParser = require('body-parser');
const chai = require('chai');
let spies = require('chai-spies');
chai.use(spies);
const expect = chai.expect;

//create app without credentials
let app = express();
app.use(express.urlencoded({ extended: false }));
app.set('view engine', 'ejs');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(route);

describe('Testing the POST /login route', () => {
  let spy = chai.spy.on(request, 'post', (options, callback) => {
    callback();
  });

  it('should make a request to backend server when form is filled, but with wrong credentials', (done) => {
    supertest(app)
      .post('/login')
      .set('Accept', 'application/json')
      .send({ username: 'test', password: 'test' })
      .end(function(err, res) {
        expect(spy).to.have.been.called.once;
        done();
      });
  });
});

单元测试结果:

  Testing the POST /login route
    ✓ should make a request to backend server when form is filled, but with wrong credentials (47ms)


  1 passing (63ms)

----------|---------|----------|---------|---------|-------------------
File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
----------|---------|----------|---------|---------|-------------------
All files |   92.31 |      100 |     100 |   92.31 |                   
 index.js |   92.31 |      100 |     100 |   92.31 | 23                
----------|---------|----------|---------|---------|-------------------