【问题标题】:How to write unit test for AngularJS model如何为 AngularJS 模型编写单元测试
【发布时间】:2013-06-27 11:31:18
【问题描述】:

我有一个基本模型,我正在尝试为其编写一个简单的单元测试套件,但我显然遗漏了一些东西......

模型的代码如下所示:

angular.module('AboutModel', [])
    .factory(
        'AboutModel',
        [
            function () {
                var paragraphs = [];
                var AboutModel = {
                    setParagraphs: function (newParagraphs) {
                        paragraphs = newParagraphs;
                    },
                    getParagraphs: function () {
                        return paragraphs;
                    }
                };

                return AboutModel;
            }
        ]
    );

要求很简单:为名为@9​​87654323@的私有数组提供getter和setter方法。

这是我所获得的测试套件代码:

describe('Testing AboutModel:', function () {
    describe('paragraphs setter', function () {
        beforeEach(module('AboutModel'));
        it('sets correct value', inject(function (model) {
            // STUCK HERE
            // don't know how to access the model, or the setParagraphs() method
        }));
    });
    describe('paragraphs getter', function () {
        // not implemented yet
    });
});

我已经在网络上做了大量的谷歌研究,但到目前为止还没有任何乐趣。

解决方案必须简单;请帮忙!

甚至可能有更好的方法来实现模型...欢迎提出建议以使其变得更好。

对于任何感兴趣的人,完整的源代码在这里: https://github.com/mcalthrop/profiles/tree/imp/angular

提前致谢

马特

【问题讨论】:

    标签: unit-testing angularjs jasmine karma-runner


    【解决方案1】:

    您需要在测试中运行 beforeEach 以注入模型实例,然后将其分配给一个变量,然后您可以在整个测试中重复使用该变量。

    var AboutModel;
    
    beforeEach(inject(function (_AboutModel_) {
      AboutModel = _AboutModel_;
    }));
    

    然后您可以像这样访问您的吸气剂:

    AboutModel.getParagraphs();
    

    我对您的原始模型进行了微调,因为我觉得它读起来更好一些(我的偏好):

    'use strict';
    
    angular.module('anExampleApp')
      .factory('AboutModel', function () {
        var _paragraphs;
    
        // Public API here
        return {
          setParagraphs: function (newParagraphs) {
            _paragraphs = newParagraphs;
          },
          getParagraphs: function () {
            return _paragraphs;
          }
        };
      });
    

    然后对于测试,我将使用标准 Jasmine 测试和 spies 的组合:

    'use strict';
    
    describe('Service: AboutModel', function () {
    
      beforeEach(module('anExampleApp'));
    
      var AboutModel, paragraphs = ['foo', 'bar'];
    
      beforeEach(inject(function (_AboutModel_) {
        AboutModel = _AboutModel_;
      }));
    
      it('should set new paragraphs array', function () {
        AboutModel.setParagraphs([]);
        expect(AboutModel.getParagraphs()).toBeDefined();
      });
    
      it('should call setter for paragraphs', function () {
        spyOn(AboutModel, 'setParagraphs');
        AboutModel.setParagraphs(paragraphs);
        expect(AboutModel.setParagraphs).toHaveBeenCalledWith(paragraphs);
      });
    
       it('should get 2 new paragraphs', function () {
        AboutModel.setParagraphs(['foo', 'bar']);
        expect(AboutModel.getParagraphs().length).toEqual(2);
      });
    
    });
    

    【讨论】:

    • 优秀!谢谢西蒙。但是有一个问题:第二次测试不是多余的吗?即,您不只是直接测试您刚刚所做的事情吗?
    • 我想认为它在测试中更加彻底 :) 第一个测试确保设置段落符合我们的预期,即将它分配给模型段落变量。第二个测试确保它将段落设置为我们通过它的确切值。有些人可能会在一种测试方法中使用多个期望来做到这一点,我更喜欢每个测试方法运行一个期望。
    • 酷。完全同意“每个测试一个断言”的方法。
    • 仅供参考,这是我为这个模型完成的单元测试:github.com/mcalthrop/profiles/blob/imp/angular/test/unit/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-15
    • 2019-12-22
    • 1970-01-01
    相关资源
    最近更新 更多