2014-10-29 57 views
0

我使用摩卡与Sinon来测试我的Angular应用程序。使用间谍方法返回承诺时遇到问题。下面是我的测试:我该如何窥探这个返回承诺的方法?

describe('product model', function() { 
    'use strict'; 

    var mockProductsResource, Product; 

    beforeEach(function() { 
     module('app.models') 

     mockProductsResource = { 
      all: sinon.spy(), 
      find: sinon.spy(), 
      create: sinon.spy() 
     }; 
     module(function($provide) { 
      $provide.value('productsResource', mockProductsResource); 
     }) 

     inject(function($injector) { 
      Product = $injector.get('Product'); 
     }) 
    }); 

    describe('module', function() { 
     // THE TEST THAT IS FAILING 
     it('should find one record', function() { 
      Product.find(1); 
      expect(mockProductsResource.find).to.should.have.been.calledOnce; 
     }); 
    }); 
}); 

在运行此我得到

TypeError: 'undefined' is not an object (evaluating 'productsResource.all().then')

,因为我对productsResource.all间谍()不返回一个承诺,我正在测试的代码,使用productsResource.all ()期望:

angular.module('app.models').factory('Product', ['productsResource', function(productsResource) { 

    // Constructor function for models 
    function Product(attributes) { 
     // ... 
    } 

    // Public "instance" methods for models 

    Product.prototype.update = function() { 
     // ... 
    }; 

    Product.prototype.save = function() { 
     // ... 
    }; 

    Product.prototype.remove = function() { 
     // ... 
    }; 


    // Public "class" methods for this factory 

    // THE METHOD I AM TESTING 
    function all() { 
     return productsResource.all().then(function(response) { 
      var products = [], index; 

      for (index in response.data) { 
       products.push(new Product(response.data[index])); 
      } 

      return products; 
     }); 
    } 

    function find(id) { 
     return productsResource.find(id).then(function(response) { 
      return new Product(response.data); 
     }); 
    } 

    function create(attributes) { 
     return productsResource.create(attributes); 
    } 

    return { 
     all: all, 
     find: find, 
     create: create 
    }; 

}]); 

任何想法如何使用间谍,并使此测试工作?

回答

0

进样$ q和

var deferred = $q.defer; 
mockProductsResource = { 
     all: function() { 
      return deferred.promise 
     }, 
     ... and so on 
}; 

sinon.spy(mockProductsResource, "all"); 

从兴农文档:

var spy = sinon.spy(object, "method");

Creates a spy for object.method and replaces the original method with the spy. The spy acts exactly like the original method in all cases. The original method can be restored by calling object.method.restore(). The returned spy is the function object which replaced the original method. spy === object.method.

+0

或者,这可能是这是一个复杂的方式。更好的方式可能是使用[模拟后端](https://docs.angularjs.org/api/ngMock/service/$httpBackend),以防$ $使用或者只是不打扰$ q并在现有方法上使用间谍(如果现有服务没有中断地返回东西)。 – Absor 2014-10-29 20:35:07