Support jQuery Promises #121

Closed
logankd opened this Issue Apr 3, 2013 · 3 comments

Projects

None yet

2 participants

@logankd

I found this blog: http://www.carlosble.com/2013/03/unit-testing-javascript-with-promises-and-jasmine/ that shows how to test promises using the when.js library. I'd like to do the same with jQuery.
I modified his code slightly and got this, which I places in my specHelper.js class, but don't have the ToHaveBeenCalledWith correct yet. I'm not sure how this relates to this issue in jasmine: jasmine/jasmine#202

Here is what I have so far, it's really clunky...
SpecHelper = {

// promise helpers
// http://www.carlosble.com/2013/03/unit-testing-javascript-with-promises-and-jasmine/
// this is just a constant, a string.
endOfPromiseChain: 'empty',
// And this is a function to ease testing:
registerPromiseError: function (target, err) {
    'use strict';
    if (err !== SpecHelper.endOfPromiseChain) {
        target.errorInPromise = err.toString();
    }
},
AssertAsyncToHaveBeenCalled: function (promiseSpy, target, additionalExpectation) {
    'use strict';
    waitsFor(function () {
        return promiseSpy.called || target.errorInPromise;
    }, 50);
    runs(function () {
        // this tells me if there was any unhandled exception:
        expect(target.errorInPromise).not.toBeDefined();
        // this asks the spy if everything was as expected:
        expect(promiseSpy).toHaveBeenCalled();
        // optional expectations:
        if (additionalExpectation) {
            additionalExpectation();
        }
    });
},
AssertAsyncToHaveBeenCalledWith: function (promiseSpy, target, haveBeenCalledWithArgs) {
    'use strict';
    waitsFor(function () {
        return promiseSpy.called || target.errorInPromise;
    }, 50);
    runs(function () {
        var i,  stringedArgs = '';
        promiseSpy.argsForCall = haveBeenCalledWithArgs;
        // this tells me if there was any unhandled exception:
        expect(target.errorInPromise).not.toBeDefined();
        // this asks the spy if everything was as expected:
        for (i = 0; i < haveBeenCalledWithArgs.length; i++) {
            stringedArgs += '\'' + haveBeenCalledWithArgs[i] + '\',';
        }
        stringedArgs = stringedArgs.substring(0, stringedArgs.length - 1);
        expect(promiseSpy).toHaveBeenCalledWith(haveBeenCalledWithArgs);
    });
},
SpyReturningPromise: function (target, methodName) {
    'use strict';
    var spyObj = spyOn(target, methodName).andCallFake(function () {
        spyObj.called = true;
        return $.Deferred().promise();
    });
    return spyObj;
}

};

Here is a test to show calling it
// where Save calls a DataContext.js Save method calls return $.ajax({....
it("should call the DataContext save method", function () {
// Arrange
// Act
vm.Save();
// Assert
SpecHelper.AssertAsyncToHaveBeenCalled(saveChangesPromiseSpy, vm.GetDataContext().SaveChanges);
//With(saveChangesPromiseSpy, vm.GetDataContext().SaveChanges, ['test', 'test']);
});

I'm sure someone can do better. Thanks!

@travisjeffery
Collaborator

This should be added in jasmine not this lib

@logankd

Ok, I'll post it in the jasmine library. Thanks for looking at it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment