【问题标题】:How can I spy on this method that returns a promise?我怎样才能窥探这个返回承诺的方法?
【发布时间】:2014-10-29 20:15:49
【问题描述】:

我正在使用 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().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
    };

}]);

任何想法如何使用间谍并使这个测试工作?

【问题讨论】:

    标签: angularjs mocha.js sinon


    【解决方案1】:

    注入 $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 创建一个 spy 并将原始方法替换为 间谍。在所有情况下,间谍的行为都与原始方法完全相同。 可以通过调用恢复原来的方法 object.method.restore()。返回的 spy 是函数对象 替换了原来的方法。 spy === object.method.

    【讨论】:

    • 或者这可能是一种复杂的方式。更好的方法可能是使用 a mock backend 以防 $http 使用,或者只是不打扰 $q 并在现有方法上使用 spy(如果现有服务返回的东西没有中断)。
    猜你喜欢
    • 2016-08-28
    • 1970-01-01
    • 1970-01-01
    • 2021-04-01
    • 2021-06-07
    • 2018-12-20
    • 1970-01-01
    • 2019-06-13
    • 2019-06-09
    相关资源
    最近更新 更多