0

我正在为快速 API 编写测试。我proxyquire习惯于stub module.exports = someFunction()依赖类型。

我有一条受保护的路线,所以我曾经proxyquire存根auth中间件。
这个auth中间件正在被存根。

在控制器中,我有一个模型,它从 db 中提取行。我也想把这个存根。
因为这是一种附加到模型的方法UserAddress。我可以直接用sinon.

像下面
let findUserAddressStub = sinon.stub(UserAdress, 'findAll').resolves({ adddre1: "address1", address2: "address2"})

但是上面的代码不起作用。findAll方法没有被存根。

我认为proxyquire是搞乱scopeexpress app

我试图用它proxyquire自己存根。
但我不知道导出对象时如何存根单个方法?

modules.exports = {
findAll: function(){},
findOne: function(){}
}

地址.test.js

const expect = require('chai').expect
const request = require('supertest')
const _ = require('lodash')
const sinon = require('sinon')
const proxyquire = require('proxyquire')
const {
    UserAddress
} = require('../../src/models')


describe('User Address /api/v1/user/addresses', function () {
    let authStub = sinon.stub().callsFake(function(req, res,next) {
        next()
    })
    authStub['@global'] = true
    const app = proxyquire('../../src/app', {
    './middlewares/auth': authStub
    });
    it('GET /api/v1/user/addresses', async () => {
        let findUserAddressStub = sinon.stub(UserAddress, 'findAll').resolves({
            id: "Z",
            address_line_1: null,
            address_line_2: null,
            city: null,
            state: "Bengaluru",
            pincode: null,
            is_deleted: false,
            landmark: null,
            map_lat: null,
            map_lng: null,
            label: null,
            service_area_id: null
        })
        const result = await request(app)
            .get('/api/v1/user/addresses')
            .set('Accept', 'application/json')
            .expect('Content-Type', /json/)
            .expect(200)
        expect(findUserAddressStub.calledOnce).to.be.true
        expect(result)
            .to.be.a('Object')
    })
})

更新
我也试过下面的代码。但它仍然无法正常工作。

 const app = proxyquire('../../src/app', {
    './middlewares/auth': authStub,
    './models/useraddress': {
        'findAll': findUserAddressStub
    }
    });

Address.js(控制器)

//Models
const {
    UserAddress
} = require('../../models')

const getAddresses = async function(req, res, next) {
    const addresses = await UserAddress.findAll({
        where: {
            user_id: req.user.id,
            is_deleted: false
        },
        attributes: {
            exclude: ["user_id", "created_by", "updated_by", "created_on", "updated_on"]
        },
        ...paginate(+req.query.page, +req.query.per_page)
    })
    return res.status(200).send({
        status: true,
        message: "Successfully fetched addresses!",
        data: addresses
    })
}

当用户通过身份验证时,我将 user_id 嵌套到中间件req内部auth并将其传递给路由处理程序。

所以我也在下面尝试

 let authStub = sinon.stub().callsFake(function(req, res,next) {
        req.user = {}
        req.user.id = 3
        next()
    })

但是,仍然findUserAddressStub没有被调用。

4

1 回答 1

1

这是一个完整的工作示例:

app.js

const express = require('express');
const app = express();
const auth = require('./middlewares/auth');
const { UserAddress } = require('./models');

app.get('/api/v1/user/addresses', auth, async (req, res) => {
  const addrs = await UserAddress.findAll();
  res.json(addrs);
});

module.exports = app;

./middlewares/auth.js

module.exports = function(req, res, next) {
  next();
};

./models/userAddress.js

module.exports = {
  findAll: function() {},
  findOne: function() {},
};

./models/index.js

module.exports = {
  UserAddress: require('./userAddress'),
};

address.test.js

const expect = require('chai').expect;
const request = require('supertest');
const sinon = require('sinon');
const proxyquire = require('proxyquire');

describe('User Address /api/v1/user/addresses', function() {
  it('GET /api/v1/user/addresses', async () => {
    let authStub = sinon.stub().callsFake(function(req, res, next) {
      next();
    });
    authStub['@global'] = true;
    let findUserAddressStub = sinon.stub().resolves({
      id: 'Z',
      address_line_1: null,
      address_line_2: null,
      city: null,
      state: 'Bengaluru',
      pincode: null,
      is_deleted: false,
      landmark: null,
      map_lat: null,
      map_lng: null,
      label: null,
      service_area_id: null,
    });
    const app = proxyquire('./app', {
      './middlewares/auth': authStub,
      './models': {
        UserAddress: {
          findAll: findUserAddressStub,
        },
      },
    });
    const result = await request(app)
      .get('/api/v1/user/addresses')
      .set('Accept', 'application/json')
      .expect('Content-Type', /json/)
      .expect(200);
    expect(findUserAddressStub.calledOnce).to.be.true;
    expect(result).to.be.a('Object');
  });
});

带有覆盖率报告的集成测试结果:

  User Address /api/v1/user/addresses
    ✓ GET /api/v1/user/addresses (2824ms)


  1 passing (3s)

----------------------|---------|----------|---------|---------|-------------------
File                  | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
----------------------|---------|----------|---------|---------|-------------------
All files             |   91.67 |      100 |      25 |   91.67 |                   
 60631196             |     100 |      100 |     100 |     100 |                   
  app.js              |     100 |      100 |     100 |     100 |                   
 60631196/middlewares |      50 |      100 |       0 |      50 |                   
  auth.js             |      50 |      100 |       0 |      50 | 2                 
 60631196/models      |     100 |      100 |       0 |     100 |                   
  index.js            |     100 |      100 |     100 |     100 |                   
  userAddress.js      |     100 |      100 |       0 |     100 |                   
----------------------|---------|----------|---------|---------|-------------------

源代码:https ://github.com/mrdulin/expressjs-research/tree/master/src/stackoverflow/60631196

于 2020-03-11T09:47:10.603 回答