Open samhatoum opened 9 years ago
Alternative to call an async callback immediately:
spyOn(Stripe.customers, 'create').and.callFake(function (data, callback) {
// Call callback immediately
var fakeError = {};
var fakeCustomer = {};
callback(fakeError, fakeCustomer);
});
Letterpress.Services.BuyService.subscribe({id: 'notNull'});
Do you really need to callback in isolation? By pulling out logic into services I usually don't need to.
The use-case you've presented is for immediate callback. The reason I need isolation is that I want to do is actually test the execution paths within the callback. So here's the full test code for context:
it('sends an email on successful subscription', function () {
// - - SETUP
spyOn(Stripe.customers, 'create').and.callThrough();
Letterpress.Services.BuyService.subscribe({id: ''});
var args = Stripe.customers.create.calls.mostRecent().args;
var callback = args[args.length - 1];
spyOn(Letterpress.Services.EmailService, 'sendConfirmation');
// - - EXECUTE
callback(null, {email: 'me@example.com'});
// - - VERIFY
expect(Letterpress.Services.EmailService.sendConfirmation).toHaveBeenCalledWith('me@example.com', 'subscribe');
});
This logic is already in a service. Here's the full code for context:
Letterpress.Services.BuyService.subscribe = function (token) {
Stripe.customers.create({
source: token.id,
plan: Meteor.settings.private.stripe.planId,
email: token.email
}, Meteor.bindEnvironment(function (err, customer) {
Letterpress.Services.EmailService.sendConfirmation(customer.email, 'subscribe');
}));
};
The callback is more of a handler
than the service
call. I could also make a structural change and create a handlers object in the BuyService
, but it seems a little overkill especially when the handler has a one-to-one relationship with its caller.
I think with this test you actually test if Stripe.customers.create
correctly calls its callback. If Stripe.customers.create
is 3rd party code, I wouldn't test that. (Just my opinion)
I'm testing the execution paths within the callback, which is stuff I write not that Stripe is calling the callback. What happens inside the callback (stripe response handler) should be tested
My current use case is a general Jasmine helper need, but I think it also applies to Meteor methods.
Consider this actualizing code:
Here's what I have to do to get the callback that I'm interested in executing in the test code:
I would a helper that I give
methodWithCallback
andParamsToPassMethodWithCallback
and it returns the callback for me. In the above example: