2014-11-14 2 views
4

Я пытаюсь проверить одну из моих функций, но часть ее использует личную переменную из контроллера. Как я могу заставить 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 || {})); 

My Jasmine test. Я пробовал иметь deliverablesKoModel быть глобальной переменной, но он всегда выходит за пределы области, когда вы используете метод выше.

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); 
    }); 

}); 

ответ

2

deliverablesKoModel является частным закодировать вне вашего IIFE.

Я не знаком с нокаутом, но есть несколько способов установить deliverablesKoModel.

  1. Сделайте это свойством вашего контроллера, который вы можете установить/получить.
  2. Сделайте ваш метод #initialize вашего контроллера прием функцией обратного вызова, которая может вернуть экземпляр вашей модели. Затем вы можете отправить функцию при вызове #initialize на своем контроллере в своем тесте.

Пример подход # 2 выше:

var deliverablesKoModel; 

myController.initialize = function(releaseId, modelCallback) { 

    // Ajax call with this success: 

    deliverablesKoModel = modelCallback(data); //returns a model 

}; 

Spec:

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); 
}); 
Смежные вопросы