sunless
sunless

Reputation: 637

Testing Angular-Resource: Expected an Object, got a Resource

When trying to test some simple angular code using $resource, I end up with a Resource object which contains a $promise key and hence a failure of the form: Failure/Error: Expected Resource(...) to equal Object(...)

I was expecting to get back the object I passed to the respond method as part of httpBackend.expectGET('/books/5.json').respond(my_book). Am I using $resource wrong or is something wrong in my test?

Code

var bookApp = angular.module('bookApp',
  [
  'ngResource',
  ]
);

function BookController(scope, $resource) {
  var ctrl = this;
  var Book = $resource('/books/:selected.json', {selected:'@id'});

  ctrl.fetch_book = function(id){
    console.log('Selecting options ' + id);
    Book.get({selected:id}, function(data){
      console.log('Received: ' + JSON.stringify(data));
      ctrl.current_book = data;
    });
  };
}

BookController.$inject = ['$scope', '$resource'];

bookApp.component('book', {
  controller: BookController
});

Test

describe('component: tree', function() {
  var component_controller, $componentController, httpBackend, my_book;

  beforeEach(module('bookApp'));

  beforeEach(inject(function($httpBackend, _$componentController_) {
    httpBackend = $httpBackend;
    $componentController = _$componentController_;
  }));

  describe('$ctrl.fetch_book(book_id)', function(){

    beforeEach(function() {
      component_controller = $componentController('book');
      my_book = {title: 'Sanctuary', id: '5'};
    });

    it('fetches the book with id=book_id', function(){
      httpBackend.expectGET('/books/5.json').respond(my_book);
      component_controller.fetch_book(5);
      httpBackend.flush();
      console.log('Options: ' + JSON.stringify(component_controller.current_book));
      console.log('constructor: ' + JSON.stringify(component_controller.current_book.constructor.name));
      expect(component_controller.current_book).toEqual(my_book);
    });
  });
});

Result

$ bundle exec teaspoon -f documentation

component: tree
  $ctrl.fetch_book(book_id)
    fetches the book with id=book_id (FAILED - 1)
      # Selecting options 5
      # Received: {"title":"Sanctuary","id":"5"}
      # Options: {"title":"Sanctuary","id":"5"}
      # constructor: "Resource"

Failures:

  1) component: tree $ctrl.fetch_book(book_id) fetches the book with id=book_id
     Failure/Error: Expected Resource({ title: 'Sanctuary', id: '5',
     $promise: Promise({ $$state: Object({ status: 1, value:
     <circular reference: Object> }) }), $resolved: true }) to equal
     Object({ title: 'Sanctuary', id: '5' }).

Finished in 0.02600 seconds
1 example, 1 failure

Upvotes: 2

Views: 2969

Answers (3)

Nazariy
Nazariy

Reputation: 727

You can try doing something like this:

expect(component_controller.current_book.toJSON()).toEqual(my_book);

I had the same issue where I got an error of

Expected object to be a kind of Object, but was Resource(

This is what I had before:

expect(self.project).toEqual(mockProject);

And after I added .toJSON() it was all good:

expect(self.project.toJSON()).toEqual(mockProject);

Hope this helps!

Upvotes: 0

Abhinav Manchanda
Abhinav Manchanda

Reputation: 6641

Try adding the following to your spec file and see if it works. I saw it in the PhoneCat example and it worked for me.

 beforeEach(function() {
    jasmine.addCustomEqualityTester(angular.equals);
  });

Upvotes: 1

Muli Yulzary
Muli Yulzary

Reputation: 2569

Try this in your tester:

expect(component_controller.current_book).toEqual(angular.toJSON(my_book));

It'll strip the object's properties and you'll have a match.

You can also try angular.equals but I haven't tested that.

Upvotes: 1

Related Questions