使用私有变量的Jasmine测试函数

时间:2014-11-14 18:34:18

标签: javascript unit-testing jasmine

我试图测试我的一个函数,但是它的一部分使用了来自控制器的私有变量。 如何让Jasmine伪造来自该私有变量的数据?

window.MyApp = window.MyApp || {};


(function(myController) {

    var deliverablesKoModel;

    myController.initialize = function(releaseId) {

        // Ajax call with this success:

        deliverablesKoModel = new knockOutModel(data); // this model contains an observable array named 'deliverables'

    };

     myController.checkDeliverableNameIsValid = function (deliverable) {

        var valid = false;

        if (ko.unwrap(deliverable.name) !== null && ko.unwrap(deliverable.name) !== undefined) {
            // PROBLEM HERE
            // when running the test deliverablesKoModel below is always undefined!
            /////////////
            valid = _.all(deliverablesKoModel.deliverables(), function(rel) {
                return (ko.unwrap(rel.name).trim().toLowerCase() !== ko.unwrap(deliverable.name).trim().toLowerCase()
                    || ko.unwrap(rel.id) === ko.unwrap(deliverable.id));
            });

        }

        deliverable.nameIsValid(valid);

        return valid;
    };


}(window.MyApp.myController = window.MyApp.myController || {}));

我的茉莉花测试。我尝试将可交付成果的KoModel作为一个全局变量,但在按上述方法时它总是超出范围。

describe("checkDeliverableNameIsValid should", function () {
    var deliverable;
    beforeEach(function () {
        window['deliverablesKoModel'] = {
            deliverables: function() {
                return fakeData.DeliverablesViewModel.Deliverables; // this is a json object matching the deliverables in the knockout model
            }
        };

        deliverable = {
            id: 1,
            name: "test 1",
            nameIsValid: function(isValid) {
                return isValid;
            }
        };
    });

    it("return false if any deliverable already exists with the same name", function () {
        var valid = myApp.myController.checkDeliverableNameIsValid(deliverable);

        expect(valid).toBe(false);
    });

});

1 个答案:

答案 0 :(得分:2)

deliverablesKoModel专用于IIFE以外的代码。

我不熟悉淘汰赛,但有几种方法可以设置deliverablesKoModel

  1. 使其成为您可以设置/获取的控制器的属性。
  2. 使控制器#initialize方法接受一个可以返回模型实例的回调函数。然后,您可以在测试中在控制器上调用#initialize时发送函数。
  3. 以上方法#2的示例:

       var deliverablesKoModel;
    
    myController.initialize = function(releaseId, modelCallback) {
    
        // Ajax call with this success:
    
        deliverablesKoModel = modelCallback(data); //returns a model
    
    };
    

    规格:

        it("return false if any deliverable already exists with the same name", function () {
        var fakeModel = function(data) {
          return {
             deliverables: function() {
                return fakeData.DeliverablesViewModel.Deliverables; 
            }
          }
        };
    
    //You didn't initialize your
     //controller, which made the "private" variable deliverablesKoModel null in your IIFE
        myApp.myController.initialize(relaseId, fakeModel);
    
        var valid = myApp.myController.checkDeliverableNameIsValid(deliverable);
    
        expect(valid).toBe(false);
    });