茉莉花测试javascript getter无法正常工作

时间:2015-11-18 22:28:02

标签: javascript angularjs jasmine

我正在为一个angularjs工厂写一些测试,但有些期望无效,我真的不知道为什么。

这是我的工厂(部分)。 'use strict';

angular.module('myAppMod')
  .factory('Person', function(BaseModel) {
    return BaseModel.extend({
      get fullname() {
        var name = [];
        if (this.first_name) {
          name.push(this.first_name);
        }
        if (this.person_extra && this.person_extra.middle_name) {
          name.push(this.person_extra.middle_name);
        }
        if (this.last_name) {
          name.push(this.last_name);
        }
        return name.join(' ');
      }
    });
  });

和Jasmine测试:

var p;
beforeEach(function() {
  p = new Person({
    first_name: 'first_name',
    person_extra: {
      middle_name: 'middle_name',
      media_item_id: null
    },
    last_name: 'last_name',
    security_level: 'security_level'
  }, true);
});

it("has a fullname", function() {
  expect(p.fullname).toEqual('first_name middle_name last_name');
});

p.fullname正在返回""(空字符串),而在工厂中console.log(this.first_name)正在undefined

非常感谢任何帮助。 提前谢谢

2 个答案:

答案 0 :(得分:6)

编辑:经过进一步调查,我改变了答案。

它无效,因为您通过get fnName() { }方法使用 getter 速记(extend)。 getter的 this是匿名对象本身,不继承Backbone模型的方法和属性,而函数属性中的this做。我做了codepen that illustrate your problem

也就是说,如果这是你的模型

 var Model = BaseModel.extend({
   get isBackboneModelThroughGetter() {
     return !!this.get;
   },
   isBackboneModel: function() {
     return !!this.get;
   },
 });

然后,Model的一个实例将使该测试通过:

it('should make you wonder', function() {
   var model = new Model();
   expect(model.isBackboneModel()).toBe(true);
   expect(model.isBackboneModelThroughGetter).not.toBe(true);
});

因此,要使您的工厂工作,您将需要:

  1. 要通过正确的Backbone呼叫替换每个媒体访问权限:this.get('propertyName')而不是this.propertyName
  2. 按功能属性替换所有 getters full_name : function() { /*...*/ }而不是get full_name() { /* ... */ }
  3. 将来自model.full_name;
  4. 的来电替换为model.full_name()

答案 1 :(得分:1)

我假设您使用的是内置angular.extendangular.extend 复制getter和setter。自2014年8月12日起,GitHub就此特定主题进行了an open issue

至于为什么它仍未实施:

  

Angular公开了它在内部使用的一些辅助函数。 extendcopy和其他许多人都是这种情况。还有其他专门研究这些功能的库,保留它们的功能   专注于那里,可以做得更好。

     

大多数用户的最佳利益是使这些辅助函数变大或变慢,因为这些函数在内部使用,并且该方向的任何更改都会对下载大小和性能产生直接影响。与此同时,需要最准确版本的应用程序应该更好地与其他库一起提供。

有很多方法可以解决这个问题。 decaf.js提供了一个适用于大多数情况的示例实现。 GitHub可能是一个更好的环境,可以深入研究它们的代码,但它归结为:

function extend (me) {
    var args = Array.prototype.slice.call(arguments, 1);
    decaf.each(args, function (o) {
        for (var key in o) {
            if (o.hasOwnProperty(key)) {
                var desc = Object.getOwnPropertyDescriptor(o, key);
                var g = desc.get;
                var s = desc.set;

                if (g || s) {
                    Object.defineProperty(me, key, { get: g, set: s, enumerable: true });
                } else {
                    me[key] = o[key];
                }
            }
        }
    });

    return me;
}