2014-10-29 74 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