Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to unit-test private methods in jquery plugins?

Perhaps this is a bit of a novice JQuery question but:

  • proper jquery plugins are written inside a closure
  • thus only methods defining the plugin interface are accessible from the outside
  • sometimes (or many times) one may need helper methods that it doesn't make sense to expose as part of plugin interface (for example because they alter internal state).
  • how do those get unit-tested?

For example, looking at blockUI plugin, how can methods install, remove, reset get unit-tested?

To draw a parallel, in Java I would:

  1. create a BlockUI interface containing public methods only (by definition)
  2. create a BlockUIImpl class implementing the above interface. This class would contain install(), remove(), reset() methods that could be public, or (package) protected

So, I would unit-test the Impl but client programmers would interact with the plugin via BlockUI interface.

like image 570
Nikita Avatar asked Apr 21 '11 22:04

Nikita


People also ask

Should you test a private method?

Generally speaking, urging to test a private methods highlights one of the following problems: We have dead code in our private method. Our private method is too complex and should belong to another class. Our method was not meant to be private in the first place.

Is it possible to test private methods in typescript?

you shouldn't, testing should only cover the public interface of your unit. Technically, in current versions of TypeScript private methods are only compile-time checked to be private - so you can call them.

How do you test a public method?

The first is to test the method through another public method that calls it. The other would be to expose it publicly even if the only thing that needs access to it are the unit tests.

Can I unit test a function that has not been exported?

When writing unit-tests for JavaScript modules, we often encounter a dilemma wherein the module has some private functions that have not been exported. Testing a function that has been exported is easy since it can be imported in the unit testing framework, and the functionality can be tested.


2 Answers

The same applies here as with any other language and testing privates: To test private methods, you should exercise them via the public interface. In other words, by calling your public methods, the private methods get tested in the process because the public methods rely on the privates.

Generally private methods are not tested separately from the public interface - the entire point is that they are implementation details, and tests should generally not know too much about the specifics of the implementation.

like image 184
Jani Hartikainen Avatar answered Sep 21 '22 13:09

Jani Hartikainen


Code written inside a function in JavaScript, or closure as you called it, is not necessarily isolated from the outside of that function.

It is useful to know that functions have visibility of the scope in which they are defined. Any closure you create carries the scope, and therefore functions, of the code that contains it.

This simple example with a jQuery plugin and an artificial "namespace" might serve to prove this assumption:

// Initialise this only when running tests
my_public_test_namespace = function(){};

jQuery.fn.makeItBlue = function() {

    makeItBlue(this);

    function makeItBlue(object) {
        object.css('color','blue');
    }

    if(typeof my_public_test_namespace != "undefined") {
        my_public_test_namespace.testHarness = function() {
            return {
                _makeItBluePrivateFn: makeItBlue
            }
        };
    }
};

$("#myElement").makeItBlue(); // make something blue, initialise plugin

console.debug(my_public_test_namespace.testHarness()._makeItBluePrivateFn);

But don't forget you shouldn't really test privates. ;)

like image 28
Zero Distraction Avatar answered Sep 21 '22 13:09

Zero Distraction