用sinon绑定条纹 - 使用stub.yields

Ale*_*lex 7 javascript node.js sinon

我正在尝试使用sinon来存储nodejs stripe api,以使用类似于以下的测试来测试客户的创建:

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);
Run Code Online (Sandbox Code Playgroud)

我的理解是stub.create.yields应该调用第一个回调,并传递它(在本例中)为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)
Run Code Online (Sandbox Code Playgroud)

错误,客户都是未定义的.

我做错了什么吗?

编辑

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

var stripe = require('stripe')(' your stripe API key ');
Run Code Online (Sandbox Code Playgroud)

因此,stripe构造函数采用api密钥

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

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

var stripe = require('stripe')('my-key-from-config');
Run Code Online (Sandbox Code Playgroud)

所以,根据你的例子,我有:

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(){});
Run Code Online (Sandbox Code Playgroud)

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;
Run Code Online (Sandbox Code Playgroud)

lam*_*tor 19

当你这样做:

var stripe = require('stripe')('my-key-from-config');
Run Code Online (Sandbox Code Playgroud)

条带库customer动态创建其他对象.所以,当你在一个文件中存根时:

test.js

var stripe = require('stripe')('test');
var stub = sinon.stub(stripe.customers, 'create');
Run Code Online (Sandbox Code Playgroud)

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

controller.js

var stripe = require('stripe')('my-key-from-config');
var controller = { ... }
Run Code Online (Sandbox Code Playgroud)

测试中的存根版本对控制器的版本没有影响.

所以....

您需要将测试实例stripe注入控制器,或使用像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'
Run Code Online (Sandbox Code Playgroud)


小智 7

看起来你正在尝试在Stripe API中将#post.cteomers.create()中的#post()函数隔离开来.@lambinator指出客户对象是在您调用时动态创建的

require('stripe')('my-key-from-config')
Run Code Online (Sandbox Code Playgroud)

require('stripe')('test')
Run Code Online (Sandbox Code Playgroud)

所以你的存根在测试中不适用于控制器中的#stripe.customers.create().

您可以将条带的测试实例注入控制器,如@lambinator建议的那样.注射几乎是最好的事情.但是,如果您正在编写橡胶符合道路类型的组件(如代理),则注射是不合适的.相反,您可以使用Stripe模块中提供的第二个导出:

Stripe.js:

...

// expose constructor as a named property to enable mocking with Sinon.JS
module.exports.Stripe = Stripe;
Run Code Online (Sandbox Code Playgroud)

测试:

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(){});
Run Code Online (Sandbox Code Playgroud)

控制器:

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);
    });
}
Run Code Online (Sandbox Code Playgroud)

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

  • 我不得不稍微调整我的存根以使其工作.`const stripeLib = require('stripe'); const stripe = stripeLib('test'); const StripeStub = sinon.stub(stripeLib.Stripe,'Stripe',function(){return stripe;});` (2认同)