我如何监视这个返回承诺的方法?

时间:2014-10-29 20:15:49

标签: angularjs mocha sinon

我使用Mocha和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'不是一个对象(评估   ' productsResource.all(),然后'。)

因为我的针对productsResource.all()的间谍没有返回一个promise,我测试的代码使用的是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
    };

}]);

如何使用间谍并使此测试有效?

1 个答案:

答案 0 :(得分:0)

注入$ q和

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

sinon.spy(mockProductsResource, "all");
来自sinon文档的

  

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

     

为object.method创建一个间谍并用原始方法替换   间谍。在所有情况下,间谍的行为与原始方法完全相同。   可以通过调用恢复原始方法   object.method.restore()。返回的间谍是函数对象   取代原来的方法。间谍=== object.method。