How to test model

Mar 13, 2014 at 2:56 PM
Hi,
Been using ExtSpec last couple of months.. Most of my tests are controller - works great, where I create spies for model and store. curious how to test model. Methods like get() and set() are part of super class (Ext.data.Model) and the test is failing.
Pasting example below. Appreciate if someone can take a look and tell me what I am doing wrong.
My Goal: model has a method changeValues(flag). If flag is true, then model gets certain values set, if flag is false different values. I want to call changeValues with true and false and verify the values set are what I expect.
------- Model class ---------
Ext.define('FW.model.AdvancedConfigModel', {
extend: 'Ext.data.Model',
fields: [
    {name: 'ARMnodes', type: 'int'},
    {name: 'CommitImage', type: 'int'},
    {name: 'PollNodes', type: 'int'},
    {name: 'MissingPacket', type: 'int'},
    {name: 'AcquireVersion', type: 'int'},
    {name: 'RebroadcastThreshold', type: 'int'},
    {name: 'SurveyEveryNthDevice', type: 'int'},
    {name: 'RebroadcastAttemps', type: 'int'}
],
config: {
    flds: ['ARMnodes', 'CommitImage', 'PollNodes', 'MissingPacket',  'AcquireVersion', 'RebroadcastThreshold', 'SurveyEveryNthDevice', 'RebroadcastAttemps'],
    normalValues: [8, 8, 8, 36, 8, 98, 2, 5],
    criticalValues: [4, 4, 4, 12, 4, 100, 1, 4]
},

changeValues: function(critical) {
    for (var i=0; i < this.getFlds().length; i++) {
        if (critical) {
            this.set(this.getFlds()[i], this.getCriticalValues()[i]);
        }
        else {
            this.set(this.getFlds()[i], this.getNormalValues()[i]);
        }
    }
}
});
-------------- My Unit test class -------------
describe('FW.model.AdvancedConfigModel', function () {
'use strict';

var model,
    esj = ExtSpec.Jasmine;

beforeEach(function () {
    this.addMatchers(esj.Matchers);
    model = ExtSpec.create('FW.model.AdvancedConfigModel');
});

describe('changeValues', function () {
    var flds = ['ARMnodes', 'CommitImage', 'PollNodes', 'MissingPacket',  'AcquireVersion', 'RebroadcastThreshold', 'SurveyEveryNthDevice', 'RebroadcastAttemps'];
    var criticalValues = [4, 4, 4, 12, 4, 100, 1, 4];
    var normalValues = [8, 8, 8, 36, 8, 98, 2, 5];
    beforeEach(function () {
        model.getFlds = jasmine.createSpy('getFlds').andReturn(flds);
        model.getNormalValues = jasmine.createSpy('getNormalValues').andReturn(normalValues);
        model.getCriticalValues = jasmine.createSpy('getCriticalValues').andReturn(criticalValues);
    });
    it('Test_changeValuesForCritical', function () {
        model.changeValues(true);
        expect(model.set).toHaveBeenCalled();
        for (var i=0; i < flds.length; i++) {
            var val = model.get(flds[i]);
            expect(val).toEqual(criticalValues[i]);
        }
    });
    it('Test_changeValuesForNormal', function () {
        model.changeValues(false);
        expect(model.set).toHaveBeenCalled();
        for (var i=0; i < flds.length; i++) {
            var val = model.get(flds[i]);
            expect(val).toEqual(normalValues[i]);
        }
    });
});
});
---------- error like below:
<failure message="test failed">TypeError: 'undefined' is not a function (evaluating 'this.set(this.getFlds()[i], this.getCriticalValues()[i])') in file:///...AdvancedConfigModel.js (line 32)</failure>
</testcase>
Coordinator
Mar 18, 2014 at 6:48 AM
Good question. You've hit an area where Ext Spec is a bit weak. As you've found, it's really best suited to controllers, view helpers or other services with dense amounts of your own business logic. It's really good at honing in on your own functions and stripping away all the stuff you didn't write.

If on the other hand you want to test how something works with all of the Ext glue (like the accessors on an Ext.data.Model), then Ext Spec isn't so helpful. If your model function is genuinely complex, then I would consider creating spies for get and set. If it's trivial, then you might test it without Ext Spec (and with Ext running).