如何在模块中存根函数?

时间:2017-06-04 11:31:44

标签: javascript testing mocking mocha sinon

我构建了快速应用程序,有一条路由A使用了许多中间件:

// fblogin.js
const saveUser = require('./middlewares').saveUser;
const issueJWT = require('./middlewares').issueJWT;

const exchangeLongTimeToken = (a) => { //return promise to call API };
const retrieveUserInfo = (b) => { //return promise to call API };

const service = {
    exchangeLongTimeToken,
    retrieveUserInfo,
};

const asyncAll = (req, res) => { 
    // use Promise.all() to get service.exchangeLongTimeToken 
    // and service.retrieveUserInfo
};

router.post('/', [asyncAll, saveUser, issueJWT], (req, res) => {
    //some logic;
});

module.exports = { router, service };

这是我的middlewares.js

const saveUser = (req, res, next) => { //save user };
const issueJWT = (req, res, next) => { //issue jwt };

module.exports = { saveUser, issueJWT };

效果很好。但是当我试着写测试时遇到了问题。 这是我的测试,我使用mocha,chai,supertest和sinon:

const sinon = require('sinon');
const middlewares = require('../../../../src/routes/api/auth/shared/middlewares');
const testData = require('../../testdata/data.json');
let app = require('../../../../src/config/expressapp').setupApp();
const request = require('supertest');
let service = require('../../../../src/routes/api/auth/facebook/fblogin').service;


describe('I want to test', () => {
    context('Let me test', function () {
        const testReq = {name: 'verySad'};

        beforeEach(() => {
            sinon.stub(middlewares, 'saveUser').callsFake((req, res, next)=>{
                console.log(req);
            });


            sinon.stub(service, 'exchangeLongTimeToken').callsFake((url) => {
                return Promise.resolve(testData.fbLongTimeToken);
            });

            sinon.stub(service, 'retrieveUserInfo').callsFake((url) => {
                return Promise.resolve(testData.fbUserInfo);
            });

        });


        it('Should return 400 when bad signedRequest', () => {

            return request(app).post(facebookAPI).send(testReq).then((response) => {
                response.status.should.be.equal(400);
            });
        });
});

有什么问题
您可以看到有3个存根,1个用于middlewares.saveUser,2个用于services.XXXX,它们位于路径的同一文件中。

问题是,2个存根有效,而middlewares.saveUser的1不工作,总是触发原始存根。

我想也许当我打电话给setupApp()时,快递会加载它需要的所有路由器,所以嘲笑它后来没有效果,但它 很奇怪,route.service可以被嘲笑......

如何让存根工作?
让它工作的唯一方法是将存根放在测试文件的顶部,就在middleware要求之后。

我试过了:
1.使用第三方模块,例如proxyquirerewire
2.使用节点自己的delete require.cache[middlewares]和' app'并重新要求他们 3.许多其他技巧。
4.使用jest的模拟,但只有当我把它放在文件的顶部时才能工作。

如果不将存根放在测试文件的顶部,解决此问题的方法是什么?谢谢!

1 个答案:

答案 0 :(得分:0)

问题中的解决方案有点受限制,因为模拟已经污染了整个测试套件。

我最终做到这一点,逻辑很简单,我们仍然需要首先模拟public ActionResult Create() { ViewBag.Error = Session["ErrorMessage"].ToString(); return View(); } ,但是我们需要所有其他变量进入测试函数而不是在文件的顶部需要它们,这次更灵活。我添加了saveUser方法来检查存根是否有效,以确保整个测试有效。

checkIfTheStubWorks