Search code examples
angularjsunit-testingjasmineangular-resource

Unit-testing ngResource $save


I have a resource which wraps a RESTful API. I use that resource from my controller to create new objects and save them, similar to this snippet from the Angular docs:

var newCard = new CreditCard({number:'0123'});
newCard.name = "Mike Smith";
newCard.$save();

When writing a unit test in Jasmine, I get the following error when the $save call is executed: "Cannot read property '$promise' of undefined".

What's the best approach to testing the method in my controller which contains the above code?


Solution

  • If you use Jasmine's spyOn() function to verify that a $resource method is called, it overwrites the original $resource method with one that implements the "spying" functionality.

    If the code in your application relies on the $resource setting the $promise property, or it relies on the returned object/array from the $resource, the Jasmine's spy function won't return anything or set a value on the $promise property. As a result, perfectly fine code in your application will fail when being tested. A similar thing happens when you use $http with the then(), success(), or error() functions.

    To work around that you can make Jasmine spy on the function as well as call the original function by doing something like this:

    // Newer Jasmine 2.0 syntax:
    spyOn(resource, "$save").and.callThrough();
    // Older syntax:
    spyOn(resource, "$save").andCallThrough();