I've been working on a simple project on Adobe Extend Script Toolkit and is having trouble implementing tests on private members. I have come up with a solution which is to expose the privates inside a callback to a special function. I'm not sure if this is a good pattern. I need suggestions.
Heres the pattern:
(function (global) {
var Loader, Require, Modules;
Require = 'Require Object';
Modules = 'Modules object';
Loader = {};
global.estk = global.estk || {};
global.estk.loader = Loader;
// This MUST be used for testing purposes only.
// Use this to test for private members.
global.estk.loader.__test__ = function (callback) {
callback.call(this, {
Require: Require,
Modules: Modules,
Loader: Loader
});
};
}($.global));
In my test file I can then call the exposed privates like this:
(function(global) {
#include '../estk/loader.jsxinc';
estk.loader.__test__(function (obj) {
$.writeln(obj.Require);
$.writeln(obj.Modules);
$.writeln(obj.Loader);
});
}($.global));
As a general rule: if you need to test private data members, you need to rethink how you're doing things. You should test that given a set of inputs, the output is what you expect. These inputs should enter at the same place they enter in the public-facing API.
Unit testing should test the public interface of your code. Testing private parts tends to result in brittle tests (tests that fail when the code changes but not the results).
See this answer as well.
So, to answer your question directly: I wouldn't say that your pattern is good. You shouldn't worry about testing private functions. Test behavior, not methods. Not every method needs a test.
Related
We're developing a mobile application and we're trying to figure out the best approach to share javascript functions across the application.
At the moment we have individual files that simply have:
var LIB = {
URL: "http://localhost/service",
connect: function() {
// connect to server
$.ajax({ url: this.URL }); // etc etc
// call a private function?
this._somethingElse();
},
_somethingElse: function() {
// do something else
}
};
Then we simply call things like:
LIB.connect(); or LIB.disconnect();
across any file.
This also gives us access to LIB.URL as well.
My question is whether this approach is the best?
I've seen people use the following approach as well, but to what benefit?
var LIB = function () {
this.URL = "http://localhost/service";
this.connect = function () {
var myself = this;
// connect to server
$.ajax({ url: this.URL }); // etc etc
// call a private function?
myself._somethingElse(); // best way to invoke a private function?
};
this._somethingElse = function () {
// do something else
};
};
This requires the following:
var lib = new LIB();
lib.connect();
EDIT:
I've also seen the following:
window.lib = (function () {
function Library () {
}
var lib = {
connect: function () {
// connect to server
}
};
return lib;
}());
I'm slightly confused with all these options.
It just depends on which you like better. I (on a personal level) prefer the former, but to each his own. The latter does have the disadvantage of requiring to either remember to declare the new before using it, or having to keep track of a already created one.
Additionally, on a technical level the first one should get slightly (as in, barely noticeable) performance, as you don't have to compute a new function.
Edit Yes, the first way is definitely the fastest.
I highly recommend going with a module system. Until ES6 comes along (http://wiki.ecmascript.org/doku.php?id=harmony:modules), you will have to use a 3rd party library in order to do this.
Each object/class/util/etc is a module.
A module exports a public api, whereas consuming modules import other modules by declaring their dependencies.
Two "standards" that exist: AMD and CommonJS. In the browser, a library like RequireJS, which uses the AMD standard, is very popular. I recommend checking out their site first: http://requirejs.org/ and see their examples.
The main advantage here is that you only expose the public api, which allows you to create a sandbox of your functionality. It's also more explicit as it's really easy to see what your module depends on, instead of relying on global objects.
There are several different approaches to structuring JavaScript code for re-usability. You can research these and decide which is best. Me personally, I have used the second approach that you've outlined. However, I separate my code into sections and actually adhere to an MVVM structure. So for instance, I have a name space called models and view models. Each of my js files begins with:
window.[APP NAME].Models.[CLASS/MODULE NAME] or window.[APP NAME].Models.[CLASS/MODULE NAME]
So, let's say I have a namespace called mynamespace and I have a module/class called myclass. My js file would begin with:
window.MYNAMESPACE = window.MYNAMESPACE || {};
window.MYNAMESPACE.ViewModels = window.MYNAMESPACE.ViewModels || {};
window.MYNAMESPACE.ViewModels.MyClass = function () {
// a public function
this.func1 = function () {
};
// a private function
function func2() {
}
};
I would then consume that class by calling:
var myClassModel = new window.MYNAMESPACE.ViewModels.MyClass();
myClassModel.func1();
This gives you some nice encapsulation of your code. Some of the other patterns you can research/google are: Prototype Pattern, Module Pattern, Revealing Module Pattern, and the Revealing Prototype Pattern.
I hope that helps but if you have any questions on what I've just said, feel free to comment on this post.
I am new to unit testing so I might be missing something, but how am I supposed to structure requirejs modules in order to make them fully testable? Consider the elegant revealing module pattern.
define([], function () {
"use strict";
var func1 = function(){
var data = func2();
};
var func2 = function(){
return db.call();
};
return {
func1 : func1
}
});
As far as I am aware of this is the most common pattern for building requirejs modules. Please correct me if I am wrong! So in this simplistic scenario I can easily test return values and behavior of func1 since it is global. However, in order to test func2 I also would have to return it's reference. Right?
return {
func1 : func1,
_test_func2 : func2
}
This makes the code slightly less pretty, but overall is still ok. However, if I wanted to mock func2 and replace its return value by using Jasmine spy I would not be able to since that method is inside a closure.
So my question is how to structure requirejs modules to be fully testable? Are there better patterns for this situation than revealing module pattern?
Are you sure you want to test the private function func2?
I think developers are missing the point of unit tests when they try writing tests for private functions.
Dependencies are what get us by the balls when developing software. And the more dependencies the tighter the squeeze . So if you have lots of tests dependant on the internal workings of a module it's going to be really painful when you want to change the internal implementation. So keep your tests dependant on the public interface, and keep the private stuff private.
My advice:
Design the public interface to your module.
Write a test against the public interface to specify some expected behaviour.
Implement the code needed to pass that test.
Refactor (if necessary)
Repeat from step 2, until all the functionality has been defined by tests, and all the tests pass.
During the implementation and refactoring stages the internals of the module will change. For example, func2 could be split up into different functions. And the danger is that if you have tests for func2 specifically, then you may have to rewrite tests when you refactor.
One of the main benefits of unit tests is that they ensure we do not break existing functionality when we change a module's internal workings. You start losing that benefit if refactoring means you need to update the tests.
If the code in func2 becomes so complex that you want to test it explicitly, then extract it into a separate module, where you define the behaviour with unit tests against the public interface. Aim for small, well tested modules that have an easy to understand public interface.
If you are looking for help with regards to unit testing I thoroughly recommend Kent Beck's book "TDD by example". Having poorly written unit tests will become a hindrance rather than a benefit, and in my opinion TDD is the only way to go.
If functions in a module call the module's other functions directly (i.e. by using references that are local to the module), there is no way to intercept these calls externally. However, if you change your module so that functions inside it call the module's functions in the same way code outside it does, then you can intercept these calls.
Here's an example that would allow what you want:
define([], function () {
"use strict";
var foo = function(){
return exports.bar();
};
var bar = function(){
return "original";
};
var exports = {
foo: foo,
bar: bar
};
return exports;
});
The key is that foo goes through exports to access bar rather than call it directly.
I've put up a runnable example here. The spec/main.spec.js file contains:
expect(moduleA.foo()).toEqual("original");
spyOn(moduleA, "bar").andReturn("patched");
expect(moduleA.foo()).toEqual("patched");
You'll notice that bar is the function patched but foo is affected by the patching.
Also, to avoid having the exports polluted by test code on a permanent basis, I've sometimes done an environmental check to determine whether the module is run in a test environment and would export functions necessary for testing only in testing mode. Here's an example of actual code I've written:
var options = module.config();
var test = options && options.test;
[...]
// For testing only
if (test) {
exports.__test = {
$modal: $modal,
reset: _reset,
is_terminating: _is_terminating
};
}
If the requirejs configuration configures my module (using config) so that it has a test option set to a true value then the exports will additionally contain a __test symbol that contains a few additional items I want to export when I'm testing the module. Otherwise, these symbols are not available.
Edit: if what bothers you about the first method above is having to prefix all calls to internal functions with exports, you could do something like this:
define(["module"], function (module) {
"use strict";
var debug = module.config().debug;
var exports = {};
/**
* #function
* #param {String} name Name of the function to export
* #param {Function} f Function to export.
* #returns {Function} A wrapper for <code>f</code>, or <code>f</code>.
*/
var _dynamic = (debug ?
function (name, f) {
exports[name] = f;
return function () {
// This call allows for future changes to arguments passed..
return exports[name].apply(this, arguments);
};
} :
_dynamic = function (name, f) { return f; });
var foo = function () {
return bar(1, 2, 3);
};
var bar = _dynamic("bar", function (a, b, c) {
return "original: called with " + a + " " + b + " " + c;
});
exports.foo = foo;
return exports;
});
When the RequireJS configuration configures the module above so that debug is true, it exports the functions wrapped by _dynamic and provides local symbols that allow referring to them without going through exports. If debug is false, then the function is not exported and is not wrapped. I've updated the example to show this method. It's moduleB in the example.
This is my second weekend playing with Node, so this is a bit newbie.
I have a js file full of common utilities that provide stuff that JavaScript doesn't. Severely clipped, it looks like this:
module.exports = {
Round: function(num, dec) {
return Math.round(num * Math.pow(10,dec)) / Math.pow(10,dec);
}
};
Many other custom code modules - also included via require() statements - need to call the utility functions. They make calls like this:
module.exports = {
Init: function(pie) {
// does lots of other stuff, but now needs to round a number
// using the custom rounding fn provided in the common util code
console.log(util.Round(pie, 2)); // ReferenceError: util is not defined
}
};
The node.js file that is actually run is very simple (well, for this example). It just require()'s in the code and kicks off the custom code's Init() fn, like this:
var util = require("./utilities.js");
var customCode = require("./programCode.js");
customCode.Init(Math.PI);
Well, this doesn't work, I get a "ReferenceError: util is not defined" coming from the customCode. I know everything in each required file is "private" and this is why the error is occuring, but I also know that the variable holding the utility code object has GOT to be stored somewhere, perhaps hanging off of global?
I searched through global but didn't see any reference to utils in there. I was thinking of using something like global.utils.Round in the custom code.
So the question is, given that the utility code could be referred to as anything really (var u, util, or utility), how in heck can I organize this so that other code modules can see these utilities?
There are at least two ways to solve this:
If you need something from another module in a file, just require it. That's the easy one.
Provide something which actually builds the module for you. I will explain this in a second.
However, your current approach won't work as the node.js module system doesn't provide globals as you might expect them from other languages. Except for the things exported with module.exports you get nothing from the required module, and the required module doesn't know anything of the requiree's environment.
Just require it
To avoid the gap mentioned above, you need to require the other module beforehand:
// -- file: ./programCode.js
var util = require(...);
module.exports = {
Init: function(pie) {
console.log(util.Round(pie, 2));
}
};
requires are cached, so don't think too much about performance at this point.
Keep it flexible
In this case you don't directly export the contents of your module. Instead, you provide a constructor that will create the actual content. This enables you to give some additional arguments, for example another version of your utility library:
// -- file: ./programCode.js
module.exports = {
create: function(util){
return {
Init: function(pie) {
console.log(util.Round(pie, 2));
}
}
}
};
// --- other file
var util = require(...);
var myModule = require('./module').create(util);
As you can see this will create a new object when you call create. As such it will consume more memory as the first approach. Thus I recommend you to just require() things.
I am using QUnit, which is excellent.
I have enclosed my JS app in the (function () {})(); sandbox. This hides a lot of code that I don't want public, but I also need to test that code.
Here is an example of how this works:
(function () {
var PublicAPI = window.PublicAPI = {};
PublicAPI.publicFunction = function (foo) {
PrivateAPI.privateFunction(foo);
return 'bar';
};
var PrivateAPI = {};
PrivateAPI.privateFunction: function (foo) {
// Make secret stuff that never gets returned to the public
// Could be an AJAX call.
}
})();
So here I can easily unit test PublicAPI.publicFunction, but how will I test PrivateAPI.privateFunction ?
This similar question sums it up pretty well... The easiest is to not deal with the private methods, as they can change if they want... The public methods are the ones that need testing. If you want to test your internal functions you need to leave a hook of some sort for qunit to be able to find.
You can't. There is no way to access it from outside of that scope. Your only hope is to integration test it, i.e. test functions on the globally available object that are using your internal functions.
Better yet: don't make private functions. What's the big deal?
I'm using the module pattern in Javascript to separate my public interface from the private implementation. To simplify what I'm doing, my code generates a chart. The chart consists of multiple parts (axises, labels, plot, legend, etc.) My code looks like:
var Graph = function() {
var private_data;
function draw_legend() { ... }
function draw_plot() { ... }
function helper_func() { ... }
...
return {
add_data: function(data) {
private_data = data;
},
draw: function() {
draw_legend()
draw_plot()
}
}
}
Some people advocate only testing the public interface of your classes, which makes sense, but I'd really like to get in some tests to test each of the components separately. If I screw up my draw_legend() function, I'd like that test to fail, not a test for the public draw() function. Am I on the wrong track here?
I could separate each of the components in different classes, for example make a Legend class. But it seems silly to create a class for what's sometimes just 5-10 lines of code, and it would be uglier because I'd need to pass in a bunch of private state. And I wouldn't be able to test my helper functions. Should I do this anyway? Should I suck it up and only test the public draw()? Or is there some other solution?
There is no way to access inner functions (private) from an outer scope. If you want to test inner functions you might consider adding a public method for testing purposes only. If you are using some sort of a build environment, for example ant, you may pre-process the javascript file for production and remove those test functions.
Actually Javascript is an Object oriented language. It's just not a statitcally typed one.
My solution is just a little bit of hack. QUnit example:
At the top of Qunit test html I have declared:
var TEST_AVAILABLE = true;
In the testable class I have a fragment like this:
if(TEST_AVAILABLE){
this.test={
hasDraft:hasDraft,
isInterpIdIn:isInterpIdIn,
// other private methods
};
}
In the QUnit you could verify
test( "hello booth", function() {
var b = new Booth();
ok(b);
ok(b.test);
ok(!b.test.hasDraft());
});
I have a similar problem. The solution I came up with is not something I like but it does the job and there's not a better solution I can find.
function Graph()
{
this.Test = function _Test(expressionStr) { return eval(expressionStr); }
var private_data;
function draw_legend() { ... }
function draw_plot() { ... }
function helper_func() { ... }
...
}
To test:
var g = new Graph();
g.Test("helper_func()") == something;
g.Test("private_data") == something2
There is an easy way actually. You can use ajax to load the script and inject a function that exposes the private functions. I have an example here that uses qUnit and jQuery. But I'm sure the same can be easily accomplished using pure Javascript.
In an object oriented language, you would typically unit test the protected methods by having the test class inherit from the class it's testing.
Of course, Javascript is not really an object oriented language, and this pattern does not allow for inheritance.
I think you either need to make your methods public, or give up on unit testing them.
There is the only one right option: Different Builds for Testing and Production
1) mark development only parts
/* test-code */
api._foo = foo
/* end-test-code */
2) strip them later... ;)
grunt.registerTask("deploy",
[
"concat",
"strip-code",
...
#philwalton has written beautiful articles:
HOW: https://philipwalton.com/articles/how-to-unit-test-private-functions-in-javascript/
WHY: https://philipwalton.com/articles/why-i-test-private-functions-in-javascript/