用sinon剔除条纹 – 使用stub.yields

我试图用sinon存根nodejs stripe api来testing客户的创build,使用如下的testing:

var sinon = require('sinon'); var stripe = require('stripe'); var controller = require('../my-controller'); var stub = sinon.stub(stripe.customers, 'create'); stub.create.yields([null, {id: 'xyz789'}]); //stub.create.yields(null, {id: 'xyz789'}); //same result with or without array controller.post(req, {}, done); 

我的理解是, stub.create.yields应该调用第一个callback,并传递它(在这种情况下)null,后面跟着一个ID为xyz789的对象。 这可能是我误解的地方

在我的'控制器'我有以下内容:

 exports.post = function(req, res, next) { stripe.customers.create({ card: req.body.stripeToken, plan: 'standard1month', email: req.body.email }, function(err, customer) { console.log('ERR = ', err) console.log('CUSTOMER = ', customer) 

错误和客户都是未定义的。

我做错了什么?

编辑

认为这个问题可能在这里:(条纹文档)

 var stripe = require('stripe')(' your stripe API key '); 

所以, stripe构造函数需要一个API键

在我的testing中,我不提供一个:var stripe = require('stripe');

但在我的控制器中,我有:

 var stripe = require('stripe')('my-key-from-config'); 

所以,按照你的例子,我有:

test.js

 var controller = require('./controller'); var sinon = require('sinon'); var stripe = require('stripe')('test'); var stub = sinon.stub(stripe.customers, 'create'); stub.yields(null, {id: 'xyz789'}); //stub.create.yields(null, {id: 'xyz789'}); //same result with or without array controller.post({}, {}, function(){}); 

controller.js

 var stripe = require('stripe')('my-key-from-config'); var controller = { post: function (req, res, done) { stripe.customers.create({ card: req.body, plan: 'standard1month', }, function(err, customer) { console.log('ERR = ', err); console.log('CUSTOMER = ', customer); }); } } module.exports = controller; 

当你这样做:

 var stripe = require('stripe')('my-key-from-config'); 

条纹库dynamic创buildcustomer和其他对象。 所以,当你把它存储在一个文件中:

test.js

 var stripe = require('stripe')('test'); var stub = sinon.stub(stripe.customers, 'create'); 

您的控制器创build另一个stripe实例在另一个文件中使用:

controller.js

 var stripe = require('stripe')('my-key-from-config'); var controller = { ... } 

来自testing的残留版本对控制器的版本没有影响。

所以….

你可能需要将stripe的testing实例注入到控制器中,或者使用像nock这样的库来模拟http级别的事情,如下所示:

  nock('https://api.stripe.com:443') .post('/v1/customers', "email=user1%40example.com&card=tok_5I6lor706YkUbj") .reply 200, object: 'customer' id: 'cus_somestripeid' 

看起来你正试图在Stripe API中从#stripe.customers.create()中分离出你的#post()函数。 @lambinator是正确的,指出客户对象是dynamic创build的,当你打电话

 require('stripe')('my-key-from-config') 

 require('stripe')('test') 

所以在testing中,你的stub不适用于控制器中的#stripe.customers.create()。

您可以将条带的testing实例注入到控制器中,如@lambinator所示。 注射是有史以来最好的事情。 但是,如果你正在编写一个橡胶 – 路上types的组件(如代理),注入是不合适的。 相反,您可以使用Stripe模块中提供的第二个导出:

Stripe.js:

 // expose constructor as a named property to enable mocking with Sinon.JS module.exports.Stripe = Stripe; 

testing:

 var sinon = require('sinon'); var stripe = require('stripe')('test'); var StripeObjectStub = sinon.stub(Stripe, 'Stripe', function(){ return stripe; }); //NOTE! This is required AFTER we've stubbed the constructor. var controller = require('./controller'); var stub = sinon.stub(stripe.customers, 'create'); stub.create.yields([null, {id: 'xyz789'}]); //stub.create.yields(null, {id: 'xyz789'}); //same result with or without array controller.post({}, {}, function(){}); 

控制器:

 require('stripe').Stripe('my-key-from-config'); var controller = { post: function (req, res, done) { stripe.customers.create({ card: req.body, plan: 'standard1month', }, function(err, customer) { console.log('ERR = ', err); console.log('CUSTOMER = ', customer); }); } 

然后在你的控制器中#stripe.customers.create()将调用你的testing存根。

这可能不是你在这里描述的内容的一部分。

yield是callArg的一个别名 ,但试图调用第一个参数是一个函数,并使用Function.prototype.apply为它提供参数 – 这意味着@psquared是正确的,说它不需要是一个数组。

但是,这不是你的问题。 试图在JSFiddle中重新创build给定的代码,我们可以看到它成功callback了参数 。

 var stripe = { customers: { create: function () {} } }; var controller = { post: function (req, res, done) { stripe.customers.create({ card: req.body, plan: 'standard1month', }, function(err, customer) { console.log('ERR = ', err); console.log('CUSTOMER = ', customer); }); } } var stub = sinon.stub(stripe.customers, 'create'); stub.yields(null, {id: 'xyz789'}); //stub.create.yields(null, {id: 'xyz789'}); //same result with or without array controller.post({}, {}, function(){}); 

这告诉我你需要展示更多的代码,或者尝试编写一个简化的testing用例来试图找出问题所在。