2015-08-18 80 views
1

我試圖在使用Sinon的測試中模擬request-promise。據我所知,Sinon嘲笑對象的方法,但request-promise只是返回一個函數。有什麼方法可以模擬一個必需的功能嗎?使用Sinon嘲笑require()'函數

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() {}); 

我也看着mockrequire和proxyquire,但我認爲他們都遇到類似的問題。

回答

1

I found a (sort of) solution here

基本上,你搭載過的callapply也將工作):

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

var User = { 
    save: function(data) { 
     return rp.call(rp, { 
      url: ..., 
      data: data 
     }); 
    } 
} 
module.exports = User; 



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

describe('User', function() { 
    it('should check that save passes data through', function() { 
     sinon.stub(rp, 'call', function(data) { 
      // check data here 
     }); 
     User.save({ foo: 'bar' }); 
    }); 
}); 

它幹得不錯,雖然我沒有做rp.call隨處可見的粉絲,所以我仍然抱着更好的解決方案的希望。

+1

更直接的解決方案是末梢rp.get,rp.post等N.B.這需要更改您自己的模塊以使用rp.get({..})/ rp.post({..})來代替rp({..})。可以說,它也更容易閱讀。 – Typhlosaurus

1

以下示例應該爲您解決問題。通過使用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; 

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); 
    }); 
});