I'm currently writing some tests for a nodejs application.
assume that I have a module like this:
module.exports = function myModule(moduleParam) {
var someVar;
....
....
function helper(param) {
return param + someVar;
}
return {
doSomething: function (bar) {
....
....
var foo = helper(bar);
....
....
}
};
};
Assume that the 'helper' function is useful only within the module and should not be exposed to the outside.
What is the 'best practice' for testing it? (of course, I can test the doSomething function as a whole,but this way, the 'helper' function is tested in a particular situation, in a 'black-box' fashion).
I'm using nodeunit as testing framework, for that metter, but I can change it on need.
You don't test it. Unit testing is black box testing. This means that the only thing you test is the public interface aka contract.
Private functions such as these only can happen from refactoring public ones.
So if you consequently use TDD your private functions are implicitly tested.
If this feels wrong it's most often because your structure is wrong. Then you should think about moving your private stuff to an extra module.
Since i find tests to be a useful tool beyond unit testing and TDD (this SO answer makes a good argument), I made an npm package to help in cases like yours: require-from.
In you example this is how you would use it:
module-file.js:
function helper(param) {
return param + someVar;
}
module.exports = function myModule(moduleParam) {
var someVar;
....
....
return {
doSomething: function (bar) {
....
....
var foo = helper(bar);
....
....
}
};
};
module.helperExports = helper;
importing-file.js:
var requireFrom = require('require-from');
var helper = requireFrom('helperExports', './module-file'));
var public = requireFrom('exports', './module-file')); // same as require('./module-file')
Related
How can I avoid the creation of global functions when compiling typescript into javascript.
Benefit: obfuscator won't have to provide a public API
Foo.ts:
class Foo {}
Foo.js:
var Foo = (function () {
function Foo() {
}
return Foo;
}());
Foo.obfuscated.js (using npm jsobfuscator):
var _0xcd14=[];var _0x12e2=[];var Foo=(function(){function Foo(){}return Foo}())
Foo is still visible. I understand why (public API). Solution would be:
Foo.isolated.js:
(function() { /* code from Foo.js */ })();
Foo.isolated.obfuscated.js (what I want):
var _0xe1f1=[];var _0xa6a8=[];(function(){var _0x64f8x2=(function(){function _0x64f8x2(){}return _0x64f8x2}())})()
Is there a typescript setup for tsconfig.js / compiler options like isolation: true or something?
Wrapping the class inside a function scope should do the trick.
(function(){
class Foo {}
})
There isn't built in support in the form of an option as far as I am aware. Let me know if doing the above does not achieve your aim - in which case some more details about exactly what the goal is will help us understand what you're going for here.
nested (private) class ?
module MyModule {
export class MyPublicClass {
private myPrivateClass: PrivateClass;
constructor() {
this.myPrivateClass = new PrivateClass;
}
public test() {
this.myPrivateClass.test();
}
}
class PrivateClass {
public test() {
console.log('it works');
}
}
}
I'm struggling with my JS code structure that's becoming apparent during my unit testing attempts. I'm used to the class structure, but I'm a bit lost in the JS world where there aren't any classes. I'm looking for a way to organize my code in the traditional class/constructor architecture. Here's what I have:
function ddGridSelector(primaryId, templateDefault, gridObj) {
//set the variables
this.primaryId = primaryId,
this.defaultTemplate = templateDefault,
this.gridObj = gridObj,
this.gridObj.searchVal = '',
this.init = ddgs_init
}
function ddgs_init(ddgs_obj) {
ddgs_setDefaultTemplate(ddgs_obj);
ddgs_initGrid(ddgs_obj);
ddgs_initKendoWindow(ddgs_obj);
ddgs_initKendoButton(ddgs_obj);
ddgs_initResetButton(ddgs_obj);
ddgs_addGridEventListener(ddgs_obj);
}
function ddgs_setDefaultTemplate(ddgs_obj) {
//doing stuff
}
function ddgs_initGrid(ddgs_obj) {
//more stuff
}
To call any of these...
var ddGridSelector_new = new ddGridSelector('PrimaryIdentifier', templateDefault, gridObj);
ddGridSelector_new.init(ddGridSelector_new);
It seems really redundant to pass my object to my function that's specified in my constructor so I'm sure I'm missing something obvious here. Really would appreciate some guidance on the matter. I think I'm close to being on a good path.
ES5 Way
You can do "functional classes" like this, which are pretty self explainable:
function User(name) {
// name is thus "private" here because it's
// not put under "this.name"
this.sayHi = function() {
alert(name);
};
}
let user = new User("John");
user.sayHi(); // John
There's also the prototype class pattern as well:
function User(name, birthday) {
this._name = name;
}
User.prototype.sayHi = function() {
alert(this._name);
};
let user = new User("John");
user.sayHi(); // John
Source/Tutorial with the examples listed here
ES6+ Way
In ES6 you can declare classes in a way that looks more like traditional programming languages:
class User {
constructor(name) {
this.name = name;
}
sayHi() {
alert(this.name);
}
}
let user = new User("John");
user.sayHi(); // John
However you will need a transplier like Babel or Typescript to compile it down to web compatible code if you are targeting platforms such as IE (all versions), Opera Mini, and the Android Browser (4.4.x, ~16% of all Android versions in the field) (web compat sources), or things such as Cordova on older iOS devices (< 10, UIWebView, etc).
Node.js should have support for classes from 4.8.4(!) and above, surprisingly enough (source).
but I'm a bit lost in the JS world where there aren't any classes.
But... there are!
class ddGridSelector {
constructor(primaryId, templateDefault, gridObj) {
//set the variables
this.primaryId = primaryId,
this.defaultTemplate = templateDefault,
this.gridObj = gridObj,
this.gridObj.searchVal = '',
}
init() {
this.setDefaultTemplate();
this.initGrid();
this.initKendoWindow();
this.initKendoButton();
this.initResetButton();
this.addGridEventListener();
}
setDefaultTemplate() {
//doing stuff
}
initGrid() {
//more stuff
}
}
I tend to love this structure for a class-like layout when I want to avoid new features. It gives you a private scope where you can scope functions and shared variables as you need them and lets you separate out a "constructor" and public methods on the prototype.
var MyType = (function () {
function MyType() {
//My Constructor
}
MyType.prototype = {
constructor: MyType,
publicMethod: privateMethod
};
function privateMethod() {
...
}
return MyType;
}());
The outer scope runs immediately and keeps the global namespace clean. We augment the private function with prototype instance methods, define any "private" methods needed, and return the private type after setup. This lets you instantiate a class like normal and call any methods.
var example = new MyType();
example.publicMethod();
What is the perpose of calling privateMethod from the publicMethod?
Can't we just define the content of privateMethod inside the public method and do the same thing ?
var basketModule = (function() {
var basket = [];
function privateMethod() {
console.log(basket);
}
return {
publicMethod: function(){
privateMethod();
}
};
})());
basketModule.publicMethod();
In your simple example, there is not really a reason for privateMethod to exist because all publicMethod does is call it, but in a more real-world example, the private methods would do things that you don't want other modules calling on their own.
For example, this is a snippet of code that I worked on today, reduced to make it a good example:
(function(){
function _renderTreeLevel() { ... }
function _backfillAllSelectedStates() { ... }
function _updateSelectedCount() { ... }
return {
render: function() {
var expandCollapse = new ExpandCollapse();
expandCollapse.render();
_renderTreeLevel(0, this.ui.treeRegion, this.treeData);
_backfillAllSelectedStates();
_updateSelectedCount((this.options.selected || []).length);
$('.collapse').collapse();
}
};
})();
The 3 "private" function that start with '_' are just functions that I put code into for refactoring and making the code cleaner and more reusable. They are not functions that I want someone to be able to call.
Users of this module should call render() only.
The reasoning is the same as any other language that has public and private members built-in, like C# or Java, but since JavaScript doesn't provide that concept, this is the pattern that people follow to provide a similar behavior.
After reading a lot of articles on singleton pattern, and making some tests, I found no difference between the singleton pattern like this (http://jsfiddle.net/bhsQC/1/):
var TheObject = function () {
var instance;
function init() {
var that = this;
var foo = 1;
function consoleIt() {
console.log(that, foo);
}
return {
bar: function () {
consoleIt()
}
};
}
return {
getInstance: function () {
if (!instance) {
instance = init();
}
return instance;
}
};
}();
var myObject = TheObject.getInstance();
myObject.bar();
and code like this (http://jsfiddle.net/9Qa9H/3/):
var myObject = function () {
var that = this;
var foo = 1;
function consoleIt() {
console.log(that, foo);
}
return {
bar: function () {
consoleIt();
}
};
}();
myObject.bar();
They both make only one instance of the object, they both can have "private" members, that points to window object in either of them. It's just that the latter one is simpler. Please, correct me if I'm wrong.
Using standard constructor like this (http://jsfiddle.net/vnpR7/2/):
var TheObject = function () {
var that = this;
var foo = 1;
function consoleIt() {
console.log(that, foo);
}
return {
bar: function () {
consoleIt();
}
};
};
var myObject = new TheObject();
myObject.bar();
has the advantage of correct usage of that, but isn't a singleton.
My question is: what are the overall advantages and disadvantages of these three approaches? (If it matters, I'm working on a web app using Dojo 1.9, so either way, this object will be inside Dojo's require).
Well, the real difference is the time of construction of the singleton. The second approach creates the singleton right away, the first only after being called the first time. Depending on what the singleton needs in memory, this might make a difference for your application. For example, you might need the singleton only if a user performs a certain action. So if the user does not do it, then it would be nice not to have to initialise the singleton at all.
Also, if the initialisation of the singleton is computationally intense, it is a good thing to be able to defer that until you really need the singleton.
Edit: And as Jani said, the last one isn't a singleton, so i didn't discuss it.
I don't think there's really a big practical difference between the first two.
The first one with getInstance behaves more like a singleton pattern in classical OOP languages like Java.
The second approach behaves more like a static class in classical OOP languages.
Obviously the issues both of these have are the same all singletons have (plenty of material for this if you look it up on google).
The last approach is not really even using new - you're returning an object from the "constructor". Obviously this one is not a singleton at all, and as such, would be the preferred approach.
I like to build singletons likes this:
function FriendHandler(){
if(FriendHandler.prototype.singleton){
return FriendHandler.prototype.singleton;
}
if(!(this instanceOf FriendHandler)){
return new FriendHandler();
}
FriendHandler.prototype.singleton = this;
...
this.selectFriends = function(firstName){
...
};
}
If you do:
new FriendHandler()
or
FriendHandler()
It always returns the same instance.
I wrote about it some months ago: http://franciscomsferreira.blogspot.com/2013/01/how-to-write-maintainable-javascript-or.html
I am currently trying to create a test suite for my javascript apps. My problem is that, it seems I cannot get access to init() from my utils object, as you can see below:
I have my app that follow a singleton pattern:
var appModal = function () {
var utils = Object.create(moduleUtils);
function init(caller, options ) {
}
}();
My test suite is in moduleUtils, this is a object literal converted to a prototype
moduleUtils.debug = {
addSlideTest : function(){
/* this function cannot fire init() from appModal */
}}
This is not possible.
You need to expose the closured functions in a publicly visible object.
For example, you can make a testMethods object in your unit tests to collect private methods. Your main file would then add private methods to the object if it exists, like this:
//In appModal
if (typeof testMethods === "object")
testMethods.init = init;
//In test suite
testMethods = { };
...
testMethods.init();