在我的单元测试沙箱中为什么它告诉我我指定的函数是一个不存在的属性?

问题描述

我的单元测试中的以下行:

sandBox.stub(myAPI,'getPeople').returns([500,{errorCode: '500'}])

给我以下错误

TypeError: 不能存根不存在的属性 getPeople

我正在尝试从我的 API 调用中存根一个错误响应,以测试我的错误处理。

单元测试:

const chai = require('chai');
const sinonChai = require('sinon-chai');
const sinon = require('sinon');
const { getPeopleHandler } = require('../services/handlers/get-people-handler');
const { expect } = chai;
const myAPI = require('../services/api');

chai.use(sinonChai);

describe('handle error',() => {
    let req;
    let res;
    let sandBox;
    describe('getPeopleHandler() with error',() => {
        before(() => {
            req = {
                session: {}
            };
            res = {
                render: () => ({})
            };

            sandBox = sinon.createSandBox();
        });
        beforeEach(() => {
            sandBox.stub(myAPI,{errorCode: '500'}]);
        })

        afterEach(() => {
            sandBox.restore();
        });

        it('should render the error page',async () => {
            sandBox.stub(res,'render').returns({});
            res.locals = {};
            await getPeopleHandler(req,res);
            expect(res.render).to.have.been.calledOnceWith('error.html');
        });
    });
});

api.js

const fetch = require('node-fetch');

const getPeople = (url) => {
    console.log(`About to call API at ${url}`);
    return new Promise((resolve,reject) => {
        fetch(url,{ method: 'GET' })
            .then(res => Promise.all([res.status,res.json()]))
            .then(([status,jsonData]) => {
                resolve([status,jsonData]);
            }).catch(error => {
                console.log('e',error)
                reject(error)
            })
    })
};

module.exports = getPeople;

get-people-handler.js

const callAPI = require('../../services/api');
const config = require('../../config/config');

const getPeopleHandler = async (req,res) => {
    const url = config.getPeopledataUrl;
    const response = await callAPI(url);
    console.log(`API call status = ${response[0]}`);
    if (response[0] === 200) {
        res.locals.list = response[1];
        res.render('people.html');
    } else {
        res.locals.error = response[0];
        res.render('error.html');
    }
};

module.exports = { getPeopleHandler };

解决方法

您存根 ) 函数是因为您使用了 getPeople。如果你想导出一个对象,你应该这样做:

module.exports

module.exports = { getPeople };

用存根函数替换 sinon.stub(object,"method")。如果该属性还不是函数,则会引发异常。

下面是一个工作示例:

object.method

api.js

const fetch = require('node-fetch'); const getPeople = (url) => { console.log(`About to call API at ${url}`); return new Promise((resolve,reject) => { fetch(url,{ method: 'GET' }) .then((res) => Promise.all([res.status,res.json()])) .then(([status,jsonData]) => { resolve([status,jsonData]); }) .catch((error) => { console.log('e',error); reject(error); }); }); }; module.exports = { getPeople };

config.js

module.exports = { getPeopledataUrl: 'http://localhost:3000/api/people',};

get-people-handler.js

const api = require('./api'); const config = require('./config'); const getPeopleHandler = async (req,res) => { const url = config.getPeopledataUrl; const response = await api.getPeople(url); console.log(`API call status = ${response[0]}`); if (response[0] === 200) { res.locals.list = response[1]; res.render('people.html'); } else { res.locals.error = response[0]; res.render('error.html'); } }; module.exports = { getPeopleHandler };

get-people-handler.test.js

测试结果:

const sinon = require('sinon');
const { getPeopleHandler } = require('./get-people-handler');
const myAPI = require('./api');

describe('handle error',() => {
  let req;
  let res;
  let sandbox;
  describe('getPeopleHandler() with error',() => {
    before(() => {
      req = {
        session: {},};
      res = {
        render: () => ({}),};

      sandbox = sinon.createSandbox();
    });
    beforeEach(() => {
      sandbox.stub(myAPI,'getPeople').returns([500,{ errorCode: '500' }]);
    });

    afterEach(() => {
      sandbox.restore();
    });

    it('should render the error page',async () => {
      sandbox.stub(res,'render').returns({});
      res.locals = {};
      await getPeopleHandler(req,res);
      sinon.assert.calledWithExactly(res.render,'error.html');
    });
  });
});

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...