使用 Sinon 模拟一个 require() 的函数

the*_*ott 2 javascript testing unit-testing mocking node.js

我正在尝试使用Sinon在测试中模拟请求承诺。据我所知,Sinon 模拟对象的方法,而 request-promise 只是返回一个函数。有没有办法模拟单个必需的功能?

var rp = require('request-promise');
var User = require('../../models/user');

// this works
sinon.stub(User, 'message', function() {});

// This is what I'd like to do to request-promise
sinon.stub(rp, function() {});
Run Code Online (Sandbox Code Playgroud)

我还研究了 mockrequire 和 proxyquire,但我认为它们都遇到了类似的问题。

PRS*_*PRS 5

下面的例子应该会为你解决问题。通过使用proxyquire,你可以用request-promise,避免磕碰.post.get.call在我看来,等干净多了。

myModule.js

'use strict';

const rp = require('request-promise');

class MyModule {
  /**
   * Sends a post request to localhost:8080 to create a character.
   */
  static createCharacter(data = {}) {
    const options = {
      method: 'POST',
      uri: 'http://localhost:8080/create-character',
      headers: {'content-type': 'application/json'},
      body: data,
    };
    return rp(options);
  }
}

module.exports = MyModule;
Run Code Online (Sandbox Code Playgroud)

myModule.spec.js

'use strict';

const proxyquire = require('proxyquire');
const sinon = require('sinon');
const requestPromiseStub = sinon.stub();
const MyModule = proxyquire('./myModule', {'request-promise': requestPromiseStub});

describe('MyModule', () => {
  it('#createCharacter', (done) => {
    // Set the mocked response we want request-promise to respond with
    const responseMock = {id: 2000, firstName: 'Mickey', lastName: 'Mouse'};
    requestPromiseStub.resolves(responseMock);
    MyModule.createCharacter({firstName: 'Mickey', lastName: 'Mouse'})
      .then((response) => {
        // add your expects / asserts here. obviously this doesn't really
        // prove anything since this is the mocked response.
        expect(response).to.have.property('firstName', 'Mickey');
        expect(response).to.have.property('lastName', 'Mouse');
        expect(response).to.have.property('id').and.is.a('number');
        done();
      })
      .catch(done);
  });
});
Run Code Online (Sandbox Code Playgroud)