AngularJS mock - 使用jasmine进行单元测试的相同服务,不同功能

时间:2015-06-23 09:51:58

标签: javascript angularjs unit-testing jasmine

我正在尝试测试服务A,这项服务有一些功能:

申请代码:

angular.module('app').factory('ServiceA', function() {
    var ServiceA = {
        _retryItem: null,

        retryItem: function(type, data) {
            ServiceA._retryItem = {
                type: type,
                data: data
            };

            return this;
        },

        clear: function() {
            ServiceA._retryItem = null;

            return this;
        },

        start: function(options, retryFn) {
            ServiceA.clear();
            ServiceA.retryItem('action', {url: '/my-url', options: options, retryFn: retryFn});
        }
    };

    return ServiceA;
});

让我们说我想测试一下这个功能"开始",我有两个选择:

1)调用实际函数clear和retryItem:

...    

describe('...', function() {
        var options, retryFn;

        beforeEach(function() {
            options = {};
            retryFn = function() {};
        });

        it('...', function() {
            ServiceA.start(options, retryFn);

            expect(ServiceA._retryItem).toEqual({type: 'action', data:  {url: '/my-url', options: options, retryFn: retryFn});

        });
    });

2)模拟两个函数clear和retryItem:

...    

describe('...', function() {
        var options, retryFn;

        beforeEach(function() {
            options = {};
            retryFn = function() {};

            spyOn(ServiceA, 'clear');
            spyOn(ServiceA, 'retryItem');
        });

        it('...', function() {
            ServiceA.start(options, retryFn);

            expect(ServiceA.clear).toHaveBeenCalled();
            expect(ServiceA.retryItem).toHaveBeenCalledWith('action', {url: '/my-url', options: options, retryFn: retryFn});
        });
    });

哪一个是正确的方法?我从单元测试中理解 - 我的单位是功能"开始",以及其他一切(功能清除和retryItem)我可以模拟并假设我有一个测试并且正在工作,这是正确的吗?

2 个答案:

答案 0 :(得分:0)

我认为这取决于你想测试什么,你有多严格和个人喜好。我会选择第二选项并分别测试其他单元测试中的剩余功能。这样你就不会多次测试一些东西,得到某种文档并且可以肯定,这些关键函数是用声音属性调用的。对我来说,听起来真的很棒! :)

答案 1 :(得分:0)

我倾向于问我正在测试的功能是做什么的。在这种情况下,start函数调用clear和retryItem。那些功能是实际正在做的工作,所有的开始就是确保那些被调用。我建议您开始测试,只检查那些其他函数是否被调用,然后专门为clear和retyItem编写测试。

您可以使用spyOn检查是否调用了其他函数。

spyOn(ServiceA, 'retryItem');

ServiceA.start(options, retryFn);

expect(ServiceA.retryItem).toHaveBeenCalled();

您还可以测试您希望传入的参数是:

expect(ServiceA.retryItem).toHaveBeenCalledWith(['Expected Parameter']);