Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jasmine test function that uses a private variable

I'm trying to test one of my functions, but part of it uses a private variable from the controller. How can I get Jasmine to fake the data from that private variable?

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. I tried having deliverablesKoModel be a global variable but it's always out of scope when hitting the method above.

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

});
like image 381
LanFeusT Avatar asked Nov 01 '22 14:11

LanFeusT


1 Answers

deliverablesKoModel is private to code outside of your IIFE.

I am not familiar with knockout, but there are a few ways to set deliverablesKoModel.

  1. Make it a property of your controller that you can set/get.
  2. Make your controller #initialize method accept a callback function which can return an instance of your model. Then, you can send in a function when calling #initialize on your controller in your test.

Example for approach #2 above:

   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);
});
like image 148
Kenrick Chien Avatar answered Nov 08 '22 04:11

Kenrick Chien