首页 > 解决方案 > 如果使用 chai-sies / Mocha / Test 调用函数(节点模块),如何测试它

问题描述

我想测试一个函数是否被 chai-sies 调用。

这是我要测试的课程

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 spie let spy = chai.spy.on(route,'request');模拟请求函数

但是当我运行代码时,它确实识别出模拟函数并返回

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

    -0
    +1

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

谢谢你的帮助。

标签: node.jsexpressmockingmocha.jschai

解决方案


您没有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                
----------|---------|----------|---------|---------|-------------------

推荐阅读