Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jasmine test for javascript getter not working

I'm writing some test for for an angularjs factory and some of the expectations are not working and I really don't know why.

This is my factory (part of it). '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(' ');
      }
    });
  });

and Jasmine tests:

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.fullnameis returning ""(empty string) and in the factory, console.log(this.first_name), is undefined.

Any help is really appreciated. Thank you in advance

like image 506
Ricbermo Avatar asked Nov 18 '15 22:11

Ricbermo


1 Answers

EDIT: After further investigation, I have changed my answer.

It is not working because you are using the getter shorthand (get fnName() { }) through the extend method. The getter's this is the anonymous object itself and does not inherit the methods and properties of the Backbone model, whereas the this in function properties do. I have made a codepen that illustrate your problem.

That is, if this is your Model

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

Then an instance of Model will make this test pass:

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

Thus, to make your Person factory work, you will need:

  1. To replace every property access by the proper Backbone call: this.get('propertyName') instead of this.propertyName
  2. Replace all getters by function properties: full_name : function() { /*...*/ } instead of get full_name() { /* ... */ }
  3. Replace calls to model.full_name by model.full_name();
like image 83
charlespwd Avatar answered Oct 23 '22 07:10

charlespwd