how to unit-test private methods in jquery plugins? - javascript

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:
create a BlockUI interface containing public methods only (by definition)
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.

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.

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

I came up with the same question and after navigating and finding answers that not really apply, here's what I ended up to solve a similar problem.
Problem: "I have a widget that has a behavior I want to test to ensure it's working as expected, some of the methods are called internally because they have to solve internal behavior, exposing them as public does not make sense because they wont be called from outside, testing the public methods means you wont test the internals of the widget, so finally what can I do?"
Solution: "Creata a test widget that exposes the methods you are interested in testing and use them in the qunit, here is the example:"
// Namespaces to avoid having conflicts with other things defined similarly
var formeditortest = formeditortest || {};
// widget that inherits from the container I want to test
$.widget( "app.testcontainer", $.app.container, {
executeDrop: function(drop, helper) {
var self = this;
self._executeDrop(drop, helper);
}
});
// Test cases
formeditortest.testDropSimple = function(assert) {
var container = $("<div />");
container.testcontainer();
container.testcontainer("drop", 0, 3);
assert.equal(true, $(innerDiv.children()[0]).hasClass("droparea"));
});
QUnit.test(name, function( assert ) {
formeditortest.testDropSimple(assert);
formeditortest.testDropBottom(assert);
});
Using this method the inherited testcontainer could have the preparation required to test elements and then the qunit will handle the test, this solves my problem, hope this works for someone else that is having troubles to approach these kind of tests.
Critics? welcome to comment, I want to improve this if I'm doing something silly!!!

Related

How to handle inheritance with public and private functions within factory functions in JavaScript?

I am the team lead of a group of ~8 developers. We look after a large website which is split into many 'components' (a component could be a gallery for example - with libraries aside, these 'components' are standalone). We are in the process of splitting things up and part of that task is creating Gulp code to handle the various stages of processing for each of these components (SCSS processing, concatenation, image optimisation etc).
So, I need to come up with a pattern that the team can follow when creating Gulp code for a new 'component'. I need to keep this as simple as possible as many of the developers are new to Gulp. The general idea I want to get to is that we have a base Gulp 'component', which will have all code required to process a standard 'component', but I expect there will be some 'components' that need special gulp code. So, I would like to be able to extend the base Gulp 'component' compilation code in these cases.
In an attempt to learn and to set up a strong foundation for the team have been doing some reading on best approaches to inheritance in JavaScript. I have come across quite a rift in the way people feel about this. What approaches I have considered and what I've gathered:
There are classes in ES6 which I can use in node.js. These classes are shunned by a lot of the big names in the JavaScript world as well as big names from the past (when using classical style languages) for reasons such as it encourages brittle code. Also, you cant do classic style public and private properties/functions, so I struggle to see any real reason why I should go with this.
If I did go this route, I feel I would end up with something like this (code is untested / probably not correct, i'm just dumping my thoughts):
class Component {
constructor(options) {
},
build() {
},
dev() {
}
test() {
},
// Should be private, but wont be
_processStyles() {
},
_processScripts() {
}
}
Factory functions. We're used to using these with the revealing module pattern, and generally I like them. I also believe that Douglas Crockford is a fan of factory functions, so I feel I'm on good ground with this. Now, if I create public and private methods (by returning an object with references only to my public functions) and then I want to extend 'component', in the new factory I would create an instance of 'component' and then extend that. The problem is that I can't override (or even call) the private functions of my 'component' instance, because they are in a different scope that I have no access to. I did read that one way to get around this is to use an object to create a reference to all of the private methods, but then they're not private anymore, so it defeats the object (no pun intended).
var component = function(options) {
var init = function() {
};
var build = function() {
};
var dev = function() {
};
var test = function() {
};
var _processStyles = function() {
};
var _processScripts = function() {
};
return {
init: init,
build: build,
dev: dev,
test: test
};
};
var specialComponent = function(options) {
// Create instance of component
var cmp = component(options);
// Extend it
cmp.extraFunction = function() {
// This will throw an error as this function is not in scope
_processStyles();
}
// Private functions are available if I need them
var _extraPrivateFunction = function() {
}
return cmp;
}
So, I feel like I've missed something somewhere, like I need someone to point me in the right direction. Am I getting too hung up about private functions (feels like it)? Are there better approaches? How would something like this, which seems to lend itself to classical inheritance be best tackled in a DRY (don't repeat yourself) manner?
Thanks in advance,
Alex.

js - How to decorate/proxy/spy on all functions? For creating a runtime profiler

So I have this decorate function that takes an object and a method-name and wraps it with external logic.
function decorate(object, methodName) {
var originalMethod = object[methodName];
object[methodName] = function () {
// pre-logic
var retVal = originalMethod.apply(this, arguments);
// post-logic
return retVal;
};
}
Now I want to wrap ALL of the functions in my application, i.e.
All the recursive public functions of the object
All private scope functions
All anonymous functions
Anything else I might have forgotten.
My purpose in doing this is to implement a "JS Profiler" that will run alongside my application during automated testing, and output performance data to logs.
I need this for testing purposes, so the solution must have minimal changes to the actual code of my application.
Possible solutions I've considered:
Public methods can be easily traversed and replaced using a recursive object traversal function.
Some hack using eval() to be able to access private methods.
Ideally, to handle all cases, I could use a proxy HTTP server (Node.js for example) that will transform each javascript file before sending it to the browser. This way my codebase will remain clean, but my tests will have the necessary changes.
The first 2 are only partial solutions, and the last one seems like an overkill and also a potential "bug factory"...
Does anyone have any other ideas on how to achieve what I need?

Encapsulation in JavaScript with protoypes

Probably many of you tried to achieve encapsulation in JavaScript. The two methods known to me are:
a bit more common I guess:
var myClass(){
var prv //and all private stuff here
//and we don't use protoype, everything is created inside scope
return {publicFunc:sth};
}
and second one:
var myClass2(){
var prv={private stuff here}
Object.defineProperty(this,'prv',{value:prv})
return {publicFunc:this.someFunc.bind(this)};
}
myClass2.prototype={
get prv(){throw 'class must be created using new keyword'},
someFunc:function(){
console.log(this.prv);
}
}
Object.freeze(myClass)
Object.freeze(myClass.prototype)
So, as second option is WAY more convenient to me (specifically in my case as it visually separates construction from workflow) the question is - are there any serious disadvantages / leaks in this case? I know it allows external code to access arguments of someFunc by
myClass.protoype.someFunc.arguments
but only in case of sloppily executed callbacks (synchronously inside caller chain). Calling them with setTimeout(cb,0) breaks chain and disallows to get arguments as well as just returning value synchronously. At least as far as i know.
Did I miss anything? It's kind of important as code will be used by external, untrusted user provided code.
I like to wrap my prototypes in a module which returns the object, this way you can use the module's scope for any private variables, protecting consumers of your object from accidentally messing with your private properties.
var MyObject = (function (dependency) {
// private (static) variables
var priv1, priv2;
// constructor
var module = function () {
// ...
};
// public interfaces
module.prototype.publicInterface1 = function () {
};
module.prototype.publicInterface2 = function () {
};
// return the object definition
return module;
})(dependency);
Then in some other file you can use it like normal:
obj = new MyObject();
Any more 'protecting' of your object is a little overkill for JavaScript imo. If someone wants to extend your object then they probably know what they're doing and you should let them!
As redbmk points out if you need private instance variables you could use a map with some unique identifier of the object as the key.
So, as second option is WAY more convenient to me (specifically in my case as it visually separates construction from workflow) the question is - are there any serious disadvantages / leaks in this case?
Hm, it doesn't really use the prototype. There's no reason to "encapsulate" anything here, as the prototype methods will only be able to use public properties - just like your untrusted code can access them. A simple
function myClass2(){
var prv = // private stuff here
Object.defineProperty(this, 'prv', {value:prv})
// optionally bind the publicFunc if you need to
}
myClass2.prototype.publicFunc = function(){
console.log(this.prv);
};
should suffice. Or you use the factory pattern, without any prototypes:
function myClass2(){
var prv = // private stuff here
return {
prv: prv,
publicFunc: function(){
console.log(this.prv); // or even just `prv`?
}
};
}
I know it allows external code to access arguments of someFunc by
myClass.protoype.someFunc.arguments
Simply use strict mode, this "feature" is disallowed there.
It's kind of important as code will be used by external, untrusted user provided code.
They will always get your secrets if the code is running in the same environment. Always. You might want to try WebWorkers instead, but notice that they're still CORS-privileged.
To enforcing encapsulation in a language that doesn't properly support private, protected and public class members I say "Meh."
I like the cleanliness of the Foo.prototype = { ... }; syntax. Making methods public also allows you to unit test all the methods in your "class". On top of that, I just simply don't trust JavaScript from a security standpoint. Always have security measures on the server protecting your system.
Go for "ease of programming and testing" and "cleanliness of code." Make it easy to write and maintain, so whichever you feel is easier to write and maintain is the answer.

Howto move from object based language to server side Node.js Javascript for big projects?

I've decided to get used to using Javascript as my server sided (I'm using Node.js) language to setup a webserver, create server deamons and a lot more. This is a rather big project, which means that I have to get used to the language and get myself an optimal setup before actually starting to avoid overhead and unneeded hassle.
I have been looking for sources that'd explain the basics of functional programming in big projects. Unfortunately, most sources talk only about basic Javascript meant for simple tricks in a browser.
Two helpful links that explained how object creation works in Javascript were http://howtonode.org/object-graphs and http://howtonode.org/object-graphs-2.
In the end, it seems most wise to create an object like:
function MyObject(constructorMemberOne, constructorMemberTwo) {
this.constructorMemberOne = constructorMemberOne;
this.constructorMemberTwo = constructorMembertwo;
this.doSomething = function doSomething() {
//
}
}
Now, I'm looking for a complete Javascript language reference. So far, https://developer.mozilla.org/en/JavaScript/Reference seems to be most complete.
Q1: is this the recommended ECMAScript language reference? I'm asking mostly because it's sourced by a company that's mostly working in the browser industry, yet Javascript is not just there for browsers -- maybe there are sources that I'm unaware of.
Secondly, I'm used to creating a new file for every class I create where the file name represents the name of the class. Q2: Is this recommended practice in Javascript (V8, Node.js) too? How would one "import" this class?
This "importing" leads me to my confusingness about Node.js's "require". I know it's not the same. Require basically loads another file which then has it's own namespace, meaning that it's variables are out of the scope of the file that's requireing this file. For my classes however, I want to have methods that are available to the class that is "importing" (quotes as I am not sure whether this is even possible) this class. Eg.:
var utils = require("utils/MainUtils.js");
utils.doSomething();
As far as I know, this doSomething() method is only available if it was set like:
function MainUtils() {
exports.doSomething = function doSomething() {
//
}
}
Q3: Is that correct? Doesn't that seem quite abnormal?
Q4: Are there any other blogs or resources that are helpful in getting my setup working, like howtonode.org?
Finally, Q5: have there been any efforts into making all this inheritance, object creation, project structure, namespacing etc. easier for big projects? Any libraries or something for this purpose?
Hopefully my questions are clear. Any help is appreciated. Thanks.
is this the recommended ECMAScript language reference?
Well the official ECMAScript language reference is the ECMA-262 itself. But unfortunately this is completely unreadable even by the standards of standards documents.
ECMA do not produce any materials aimed at end-programmers and there's no one tutorial considered “best”. The MDC link looks decent, at least. (Most JavaScript tutorials are absolutely horrible and full of errors. Which is partly JavaScript's fault for having so many... quirky... features, but still.)
In the end, it seems most wise to create an object like:
There is unfortunately no widely-accepted-‘best’ way to implement a class/instance system in JavaScript. A lot of frameworks have their own systems, or you can brew your own. Your example code creates a new instance of each method for each object instance, which you might consider suboptimal compared to JS's native prototyping. (Normally this approach is used with a var that= this in the closure to avoid this-binding problems in callback code.) You would also need to exercise care in how you create subclasses and initialise them in the constructors.
See this question for a discussion on approaches to class/instance in JS.
I'm used to creating a new file for every class I create
Yeah, that's a Java wart you shouldn't bring to JS.
Keep your source files in manageable chunks of related classes and functions. Sometimes that will be one public class per file, more often it won't be.
How would one "import" this class?
JS itself has no native import functionality. In browsers you do it by inserting <script> tags or eval​ing code fetched by XMLHttpRequest, and have to take care of keeping variables in separate namespaces manually. In Node.js and other places where you're working with CommonJS, you use modules and require().
Is that correct?
Yes.
Doesn't that seem quite abnormal?
I don't think so. It's similar to other scripting languages, where it proves very useful. It's only really Java that forces you to wrap up a compilation unit into a single class.
I came up with the following after reading a book called Pro Javascript Design Patterns. However, I've been told that it's not good to think like this (private, public, static, etc.) in Javascript:
var SomeClass = (function() {
this.prototype.publicStaticMember = "this is a public static variable",
this.prototype.publicStaticMethod = function() {
return "this is a public method: cannot access private members/methods, but can access privileged and public members/methods";
}
var privateStaticMember = "this is a private static variable";
function privateStaticMethod() {
return "this is a private static method: can only access private members/methods";
}
//instance part
return function() {
this.publicInstanceMember = "this is a public instance variable";
var privateInstanceMember = "this is a private instance variable";
this.publicInstanceMethod = function() {
return "this is a privileged method: can access both public and private members/methods";
}
var privateInstanceMethod = function() {
return "this is a private method: can access both public and private members/methods but is private";
}
}
})();
It'd be instantiated like this:
var someInstance = new SomeClass().("param1", "param2");
Any comments? Should I read an other book?
If you haven't already, checkout the videos by Douglas Crockford. He has a bunch of videos that talk about the prototypal aspects of JavaScript.
Google for 'Douglas Crockford Java Programming Language Video'. Here is a link to the first part in the series: http://video.yahoo.com/watch/111593/1710507
The defineClass npm package provides simple yet powerful OOP for JavaScript with support for traits (mixins) and nested classes. Here is an example of usage:
var defineClass = require("defineClass").defineClass;
var Person = defineClass({
cash: 0,
constructor: function (firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
},
greet: function (name) {
console.log("Hello " + name + ". My name is " + this.firstName);
},
earn: function (amount) {
this.cash += amount;
}
});
var Developer = defineClass({
_super: Person,
// override a field default value
cash: 100,
// override the constructor
constructor: function (firstName, lastName, language) {
// you may have code before the base constructor call
// call the base constructor
this._super(firstName, lastName);
this.language = language;
}
// override a method
greet: function (name) {
console.log("Hey, " + name + ". I'm " + this.firstName)
},
// override a method and call its base method
earn: function (amount) {
return this._super(amount * 1.2);
}
});
Read more in the readme: https://github.com/nodirt/defineClass
Installation:
$ npm install defineClass

How do I mimic access modifiers in JavaScript with the Prototype library?

I've been working with the prototype library for some time now and occasionally find myself wishing I had multiple access levels (public, private, and protected). The closest I've come so far is the following:
SampleBase = Class.create({
/* virtual public constructor */
initialize: function(arg1, arg2)
{
// private variables
var privateVar1, privateVar2;
// private methods
var privateMethod1 = function() { }
function privateMethod2() { }
// public (non virtual) methods
this.publicNonVirtual1 = function() { return privateVar1; }
this.publicNonVirtual2 = function() { return privateVar2; }
},
// public methods (that cannot access privates)
publicVirtual1: function() { /* Cannot access privates here. */ },
publicVirtual2: function() { /* Cannot access privates here. */ }
});
This less then ideal for several reasons:
No protected level
I can have public members that can access private members or public members that can be overridden but not not public member that can access private members and be overridden.
My public methods that can be overridden are not prototyped.
I've done some searching but haven't found anything that suggests I can do better without altering how prototype works. Here's some of the more interesting links:
Using Prototype’s Class.create to define private/protected properties and methods
JavaScript private methods
Private Members in JavaScript
Again with the Module Pattern – reveal something to the world
I've seen it suggested that you can provide accessors for my public virtual methods to use by doing something like this:
Message = Class.create({
initialize: function(message)
{
var _message = message;
this.getMessage = function() { return _message; }
this.setMessage = function(value) { _message = value; }
},
printMessage: function() { console.log(this.getMessage()); },
appendToMessage: function(value) { this.setMessage(this.getMessage() + value); }
});
This clearly will not work as intended. The goal is to only allow printing and appending to the message from outside of the object. The setter provided to make the virtual public function work also allows full control of the message. It could be changed to make the virtual method little more then a shell as follows:
Message = Class.create({
initialize: function(message)
{
var _message = message;
this._printMessage = function() { console.log(_message); }
this._appendToMessage = function(value) { _message += value; }
},
printMessage: function() {this._printMessage(); },
appendToMessage: function(value) { this._appendToMessage(value); }
});
This new version does limit public access for this class but is somewhat redundant. Not to mention if appendToMessage is overriden in a subclass a third party can still call _appendToMessage to access the original method which is not good.
I do have a very dirty idea that will get me close but is a can of worms I'd rather not open. I may post it later but in the mean time does anyone have suggestions for merging the two types of public methods into one useful type or on how to implement protected members.
EDIT:
I suspect the lack of feedback (aside from bobince's don't bother comment) mean that I am correct in that you can't take it any farther but I think I'll clarify a little just in case. I don't think it is possible to get anything close to the protection of other languages. I'm more interested in knowing where the limits lie and how accurate my understanding of the principles involved are. I do however think it would be interesting, if not useful, if we could get the various protection levels functioning to the point that non public members don't show up in a for...in loop (or in Prototypes Object.keys which uses for..in) even if it people who know what they are doing can still break the rules by doing things like tinkering with my prototypes. Afterall, its like bobince says " they have no-one to blame but themselves"
Now to comment on an issue raised by bobince:
Even if you made real
private/protected variables it still
wouldn't get you the full
encapsulation an effective security
boundary would require. JavaScript's
ability to fiddle with the prototypes
of built-in types your methods will be
using gives an attacker the ability to
sabotage the methods.
This is one limitation I do understand and I probably should have mentioned above. However, I am not looking at this from the point of view of protecting my code from someone trying to "hack" it. However, I do have a few things that may be worth noting (or in need of correcting if I am wrong):
Only my public members are vulnerable in this way.
If my public virtual methods are "compromised" in this way, then the "compromised" methods will still not have access to the private members.
If my public (non virtual) members are "compromised" in this way, then, unlike the original version of the method, the "compromised" version will not have access to the private memebers.
As far as i know the only way to gain accesses to the private members by methods defined outside of initialize method is too take advantage of a bug in the way some browsers handle eval calls.
How to make a protected member in JavaScript: put an underscore at the start of the name.
Seriously, you're not going to have security boundaries within a JS script that would make real proper protection necessary. Access levels are a trad-OO coder's obsession that make no sense in the context of web scripting. Even if you made real private/protected variables it still wouldn't get you the full encapsulation an effective security boundary would require. JavaScript's ability to fiddle with the prototypes of built-in types your methods will be using gives an attacker the ability to sabotage the methods.
So don't bother try. Just do like the Pythoners do: flag the method as something outsiders shouldn't be calling, and be done with it. If someone uses your code and relies on a member with _ at the start of the name, that's their problem and they have no-one to blame but themselves when their script breaks. Meanwhile you'll make the development and debugging stages easier for yourself by not having strict private and protected members.
Then you can choose per-instance-members (for callback binding convenience) or prototyped members (for efficiency), whether or not you intend them to be private, and you won't trip yourself up on the inconsistency.
http://www.crockford.com/javascript/private.html
Explains it all...

Categories

Resources