2

I have a function that hides and shows items on my page based on what a factory provides me:

function toggleMenuItems(config) {
        // hide all our elements first
        $(".js-quickMenuElement").hide();

        config.data = config.data || [];
        config.data.forEach(function (d) {

            if (d === config.viewConfigCatalog.CalendarLink) {
                $("#CalendarLink.js-quickMenuElement").show();
            }

            if (d === config.viewConfigCatalog.ProductCreation) {
                $("#ProductCreation.js-quickMenuElement").show();
            }

            // etc etc etc

        });

    };

We've been using Jasmine for our javascript unit tests and we're discussing whether we should test this function. Some say that we don't need to because testing this is coupling the view to the javascript test, but at the same time, if instead of jquery .show and .hide functions those were wrappers, or other functions we would test them.

Following on this what would be the best way to test this? Making a wrapper function that takes in a string and injects the string name in the jQuery select seems wrong. Another option we thought of is spying on ($.fn, "show") but that would only let us test if show was called X amount of time and not what was hidden...

Thanks,

RoboKozo
  • 4,981
  • 5
  • 51
  • 79
LanFeusT
  • 2,392
  • 5
  • 38
  • 53

1 Answers1

1

You can use jQuery to test the visibility of an element.

$(element).is(":visible");

code taken from a related question

Of course in doing this as you say you're coupling the view with the test. You could move the logic which determines the outcome of this function into a separate function and then test that functions result instead.

** Edit **

Below illustrates what I meant regarding simplification with a KVP list, and you could write a test for the function which gets the value from the KVP.

var config = {
  data: [],
  viewConfigCatalog: {
    CalendarLink: "CalendarLink",
    ProductCreation: "ProductCreation",
  }
};

var kvp = [{
  name: config.viewConfigCatalog.CalendarLink,
  value: "#CalendarLink.js-quickMenuElement"
}, {
  name: config.viewConfigCatalog.ProductCreation,
  value: "#ProductCreation.js-quickMenuElement"
}];

function getSelectorString(name) {
  var i = kvp.length;
  while (i--) {
    var pair = kvp[i];
    if (pair.name === name)
      return pair.value;
  }
  return null;
}

function toggleMenuItems(config) {
  // hide all our elements first
  $(".js-quickMenuElement").hide();

  config.data = config.data || [];
  config.data.forEach(function(d) {
    $(getSelectorString(d)).show();
  });

};

document.writeln(getSelectorString(config.viewConfigCatalog.CalendarLink)+'<br/>');
document.writeln(getSelectorString(config.viewConfigCatalog.ProductCreation)+'<br/>');
document.writeln(getSelectorString("hi"));
Community
  • 1
  • 1
Chris
  • 2,766
  • 1
  • 29
  • 34
  • The dom doesn't exist in the jasmine test, so .is(":visible") isn't something I can or even want to be doing. The question really is whether we should be testing this function or not. Moving the logic would work but then you're still coupling the view with the test since you would pass in the jQuery selector string... – LanFeusT Apr 28 '15 at 16:57
  • What sparked the question of whether or not you should test this code? You could perhaps simplify it a bit by using a key-value-pair list of `config.viewConfigCatalog` values as the key, and selector strings as the values. Then you could test that functionality. You would thereafter have to make sure your KVP list is correct. – Chris Apr 28 '15 at 17:14
  • We didn't want to have a test coupled to the view, which is what started the question about testing it or not, but I like your solution of a key-value-pair. Thanks! – LanFeusT Apr 28 '15 at 19:40