Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Testing JavaScript functions inside anonymous functions

Is it possible to test myInnerFunction below?

var val = function() {
    var myInnerfunction = function(input) {
        return input + ' I ADDED THIS';
    };
    return myInnerfunction('test value');
}();

Because myInnerFunction is essentially a private member of the anonymously executed outer function, it doesn't seem like it is testable from the outside.

like image 793
Matthew Taylor Avatar asked Dec 10 '09 13:12

Matthew Taylor


People also ask

Does JavaScript support anonymous function?

Anonymous Function is a function that does not have any name associated with it. Normally we use the function keyword before the function name to define a function in JavaScript, however, in anonymous functions in JavaScript, we use only the function keyword without the function name.

Can anonymous function return JavaScript?

They are always invoked (called) using the variable name. Also, we create anonymous functions in JavaScript, where we want to use functions as values. In other words, we can store the value returned by an anonymous function in a variable.

How do you beat anonymous function?

The syntax is simple: you can simply declare the anonymous function and make it execute by just calling it using the parenthesis at the end of the function. You can simply pass the parameters inside the immediate execution of the anonymous function as we have seen in the above example.

What are two common uses of anonymous functions in JavaScript?

One common use for anonymous functions is as arguments to other functions. Another common use is as a closure, for which see also the Closures chapter. Use as an argument to other functions: setTimeout(function() { alert('hello'); }, 1000);


2 Answers

You could intentionally expose a testing hook to the outside world, like possibly this:

var val = function() {
   var myInnerfunction = function(input) {
      return input + ' I ADDED THIS';
   };
   /* START test hook */
   arguments.callee.__test_inner = myInnerFunction;
   /* END test hook */
   return myInnerfunction('test value');
}();

now, once val has been run at least once, you can reference val.__test_inner and call it with testable inputs.

The benefits to this approach: 1. you choose what is exposed and not (also a negative 'cause you have to REMEMBER to do so) 2. all you get is a copy-reference to the private method, so you can't accidentally change it, only use it and see what it produces

The drawbacks: 1. if the private member changes (or relies on) state of its host/parent function, it's harder for you to unit test around that, since you have to recreate or artificially control the host/parent state at the same time 2. As mentioned, these hooks have to be manually added

If you got really clever, you could have your build process look for blocks of comments like the above and remove the test hooks when creating your production build.

like image 69
Kyle Simpson Avatar answered Oct 22 '22 23:10

Kyle Simpson


afaik unit testing does not concern about internal workings of things you test. The point is that you test the functionality ie: it does what it's supposed to do, not how it does it. So if it uses an internal private member, it should not be testable...

like image 40
NDM Avatar answered Oct 22 '22 23:10

NDM