I have following code in a file named index.js. I want to test some functions in it add, print being the prime one.
(function($){
"use strict";
$(function(){
var add = function(a, b){
// ...
},
print = function(str){
// ...
},
setup = function(){
// ...
},
init = function(){
// ...
};
setup();
init();
});
})(jQuery);
How can I do so?
Does this way of coding add any security on client side? All I have is code that runs on the client side. No server involvement what-so-ever.
I tried :
var outerObj = (function(greet){
var innerObj = (function(){
return {test: function(){ console.log(greet); }}
})();
return innerObj;
})("hi");
outerObj.test();
but, in my case, innerObj line has a $ on the right hand of equal sign, making console yell error that shouts $(...) is not a function.
Which I agree, it's an array of single document object.
Check out var a = (function(){ var val = $(function(){return 10;})(); })(); in any jquery enabled web-page's console, for the error.
Even if I ditch outer shell and bring $(function() {}); out. How am I gonna test that?
It's still an object, still an error.
What kind of testing can I perform, unit, bdd, etc. and how?
I don't quite see what pattern you're using here - it seems like a bit of an anti-pattern. It's not testable, and doesn't expose any behaviour for real world use. I'd highly recommend reading (or at least skimming) Javascript Design Patterns by Addy Osmani, available for free.
For Unit Testing, I've always found a happy midpoint between the simple constructor pattern and revealing module pattern easiest to work with.
var x = function($){
"use strict";
var add = function(a, b){
alert('add');
},
print = function(str){
return 1;
},
setup = function(){
alert('setup');
},
init = function(){
alert('init');
};
init();
setup();
return {
add: add,
print: print
};
};
var y = new x(jQuery);
In the above example, y will have the add and print methods available. Check out a sample test on this fiddle.
As a side note, I've recently been using the excellent QUnit framework for setting up and running my JS Unit Tests. It's by the jQuery Team, so you know it's gonna be good ;).
I'd also suggest checking out BlanketJS for reporting on coverage, and qunit-parameterize for setting up multiple test cases.
For what its worth, BDD isn't a 'test type', but a way of working. For what tests you should have - Unit Tests and Integration Tests are the most important 2, IMO. I use QUnit for Unit Tests, and Selenium with NUnit for Integration Testing.
Related
I am new for unit test and TDD method so could you help me please.
function calculate(a, b) {
var sum = a + b;
var sub = a - b;
return { sum: sum, sub: sub };
}
With jest you can do it like this :
describe('calculation', ()=> {
let result
beforEach(()=>{
result = calculate(2, 3)
})
it('returns the correct sum', (){
expect(result.sum).toBe(5)
})
it('returns the correct sub', (){
expect(result.sub).toBe(-1)
})
})
it('checks calculations', function() {
var calculate = require('./example.js');
expect(calculate(1, -1).sum).toBe(0);
expect(calculate(1, -1).sub).toBe(2);
});
Save the file as a .js and use npm test.
I am assuming that you are using jestjs.
You can definitely add other test conditions depending upon your understanding of the function.
A very different answer here: the huge problem with testing such code manually is the fact that it is hard to tell when you wrote enough tests covering different cases.
An alternative approach here: instead of specifying only expected results you step back and identify the contracts that your method under test should adhere to.
And then you use one of the quickcheck-based frameworks, such as JSVerify. You give those rules to the tool - and then the tool creates random data and runs test cases. And it case it finds violations of the contract, it will then try to "minimize" the test input - so that you, in the end receive a message "when you use this data x,y,z then rule A is violated".
It is a very different approach compared to "normal" TDD and unit testing, but especially for such kind of functionality it can be a very effective additional thing to do.
I'm very new to unit testing (this is my first day working with QUnit and I've never worked with anything other testng system before), and I'm a bit unclear on how to test stuff from multiple script files in one QUnit page without letting the scripts interact with each other. What I mean is, say, if I have script1.js, and it calls hello(), and hello() is defined in script2.js, how can I run a unit test on script1.js to make sure it calls hello(), but mock the output of hello() so that it's a true unit test, and then run script2.js's hello().
Basically, how am I supposed to hide one script's global variables and functions from another script in a single QUnit page?
This depends entirely on how the various script files are organized as well as the system as a whole. If you were using Angular, for example, then you are able to inject dependencies when you include a module in another script file. There are tools for mocking out things and "spying" on function calls such as Sinon, but it still depends heavily on how your code is organized.
For the sake of argument, let's say the two files look like so, and we'll ignore the design pattern (although you should seriously be considering that)...
// File A:
window.greeting = function() {
var world = hello();
return 'hello ' + world;
}
// File B:
window.hello = function() {
// possibly lots of code to determine what to return...
var value = 'foobar';
return value;
}
The hello() function could just as easily return any other value based on the state of the system, user input, etc. For our case it doesn't, and what we want to do is mock out File B's code so that we don't have to test what it is doing, just that it gives back a string. We could (and should) do this with a proper mocking/dependency injection library. However, just to give you a sense of the minimal setup you could do, and to see the general approach, here's our QUnit test file:
var _hello;
QUnit.module('File A', {
setup: function() {
_hello = window.hello; // hold onto the old value
// now we mock out hello()
window.hello = function() {
window.hello.called++; // track calls to it
return 'world'; // return our static value
}
window.hello.called = 0;
},
teardown: function() {
// put the old one back
window.hello = _hello || window.hello;
}
});
QUnit.test('Ensure greeting is correct', function(assert) {
var result = greeting();
assert.equal(window.hello.called, 1, 'hello should be called only once');
assert.equal(result, 'hello world', 'The greeting call should be "hello world"');
});
And if you want to see it running, here is a jsfiddle for you. As I said, this is a simple example to show you how you could do this, but you should look into proper code organization (think AMD modules, require, Angular, Ember, things like this) and a proper mocking library.
I'm trying to write 'better' javascript.
Below is one pattern I've found, and am trying to adopt. However, I'm slightly confused about its use.
Say, for example, I've got a page called "Jobs". Any JS functionality on that page would be encapsulated in something like:
window.jobs = (function(jobs, $, undefined){
return {
addNew: function(){
// job-adding code
}
}
})(window.jobs|| {}, jQuery);
$(function(){
$('.add_job').on('click', function(event){
event.preventDefault();
window.jobs.addNew();
});
});
As you can probably deduct, all I've done is replaced all the code that would have sat inside the anonymous event-handler function, with a call to a function in my global jobs object. I'm not sure why that's a good thing, other than it's reduced the possibility of variable collisions and made the whole thing a bit neater, but that's good enough for me.
The - probably fairly obvious - question is: all my event-binding init-type stuff is still sitting outside my shiny new jobs object: where should it be? Inside the jobs object? Inside the return object inside the jobs object? Inside an init() function?
I'm just trying to get a sense of a stable, basic framework for putting simple functionality in. I'm not building JS apps, I'd just like to write code that's a little more robust and maintainable than it is currently. Any and all suggestions are warmly welcomed :)
You can break down your application in whatever number of modules / objects you like too.
For instance, you can have another object / module which caches and defines all your DOM nodes and another one, which just handles any event. So for instance:
(function ( win, doc, $, undef ) {
win.myApp = win.myApp || { };
var eventHandler = {
onJobClick: function( event ) {
event.preventDefault();
myApp.addNew();
}
};
var nodes = (function() {
var rootNode = $( '.myRootNode' ),
addJob = rootNode.find( '.add_job' );
return {
rootNode: rootNode,
addJob: addJob
};
}());
$(function() {
myApp.nodes.addJob.on( 'click', myApp.handler.onJobClick );
});
myApp.nodes = nodes;
myApp.handler = eventHandler;
}( this, this.document, jQuery ));
It doesn't really matter how you create singletons in this (module) pattern, either as literal, constructor, Object.create() or whatnot. It needs to fit your requirements.
But you should try to create as many specific modules/objects as necesarry. Of course, if makes even more sense to separate those singletons / modules / objects into multiple javascript files and load them on demand and before you can say knife, you're in the world of modular programming patterns, dealing with requireJS and AMD or CommonJS modules.
Encapsulation-wise, you're fine: you could even just declare addNew in the jQuery closure and you'd still avoid the global scope. I think what you're getting at is more of implementing something close to an MVC architecture.
Something I like to do is create an object that you instantiate with a DOM element and that takes care of its own bindings/provides methods to access its controls etc.
Example:
// (pretend we're inside a closure already)
var myObj = function(args){
this.el = args.el; // just a selector, e.g. #myId
this.html = args.html;
this.bindings = args.bindings || {};
}
myObj.prototype.appendTo = function(elem){
elem.innerHTML += this.html;
this.bindControls();
};
myObj.prototype.remove = function(){
$(this.el).remove(); // using jQuery
};
myObj.prototype.bindControls = function(){
for(var i in this.bindings){ // event#selector : function
var boundFunc = function(e){ return this.bindings[i].call(this,e); };
$(this.el).on(i,boundFunc);
}
};
The way you are doing it right now is exactly how I do it also, I typically create the window objects inside the anonymous function itself and then declare inside that (in this case: jClass = window.jClass).
(function (jClass, $, undefined) {
/// <param name="$" type="jQuery" />
var VERSION = '1.31';
UPDATED_DATE = '7/20/2012';
// Private Namespace Variables
var _self = jClass; // internal self-reference
jClass = window.jClass; // (fix for intellisense)
$ = jQuery; // save rights to jQuery (also fixes vsdoc Intellisense)
// I init my namespace from inside itself
$(function () {
jClass.init('branchName');
});
jClass.init = function(branch) {
this._branch = branch;
this._globalFunctionality({ globalDatePicker: true });
this._jQueryValidateAdditions();
//put GLOBAL IMAGES to preload in the array
this._preloadImages( [''] );
this._log('*******************************************************');
this._log('jClass Loaded Successfully :: v' + VERSION + ' :: Last Updated: ' + UPDATED_DATE);
this._log('*******************************************************\n');
};
jClass._log = function() {
//NOTE: Global Log (cross browser Console.log - for Testing purposes)
//ENDNOTE
try { console.log.apply(console, arguments); }
catch (e) {
try { opera.postError.apply(opera, arguments); }
catch (e) { /* IE Currently shut OFF : alert(Array.prototype.join.call(arguments, ' '));*/ }
}
};
}(window.jClass= window.jClass|| {}, jQuery));
The reason I leave them completely anonymous like this, is that let's say in another file I want to add much more functionality to this jClass. I simply create another:
(function jClass, $, undefined) {
jClass.newFunction = function (params) {
// new stuff here
};
}(window.jClass = window.jClass || {}, jQuery))
As you can see I prefer the object.object notation, but you can use object literals object : object, it's up to you!
Either way by leaving all of this separate, and encapsulated without actual page logic makes it easier to have this within a globalJS file and every page on your site able to use it. Such as the example below.
jClass._log('log this text for me');
You don't want to intertwine model logic with your business logic, so your on the right path separating the two, and allowing for your global namespace/class/etc to be more flexible!
You can find here a comprehensive study on module pattern here: http://www.adequatelygood.com/JavaScript-Module-Pattern-In-Depth.html It covers all the aspects of block-scoped module approach. However in practice you gonna have quite a number files encapsulating you code, so the question is how to combine them property. AMD... multiple HTTP requests produced by every module loading will rather harm your page response time. So you can go with CommonJS compiled to a single JavaScript file suitable for in-browser use. Take a look how easy it is http://dsheiko.github.io/cjsc/
I would like to verify with selenium that certain method (with parameters) was called on
JavaScript Object - kind of expectation mocking with JMockit, but in Javascript and selenium.
Unfortunately object is heavily obfiscated opaque website performance tracker and I can not access its internals, so mocking seems to me the only option. Or do I miss something obvious?
Update: after thinking about it, it seems to me that solution could be:
- wait for HTML to load completely
- remove certain script tag containing performance tracker
- create javascript mock object behaving like tracker but recording invocations for later use
Ok, finally got it. Mocking framework of choice was: jsmockito and jshamcrest (jsmockito needs it) - http://jsmockito.org/
And it was peace of cake.
Spy on existing object:
<tr>
<td>storeEval</td>
<td>window.wwa = JsMockito.spy(window.wwa$); </td>
<td>mockedWipe</td>
... do whatever necessary
and verify it:
<tr>
<td>storeEval</td>
<td>JsMockito.verify(window.wwa$).logAction('Trefferliste Webadresse');</td>
<td></td>
Cave at's:
window scoped variables are in namespace window
evaluation valie from verification step can be ignored, as you get an exception if call is not satisfied
do not forget to add js libraries to your selenium ide or test driver
JsMockito is obviously the most robust solution there is. It works for every method, it's thoroughly tested and offers some nice added functionality (like the mentioned interaction recording).
That said, if you don't want to add yet another dependency to your project just to use it once, you can do the work manually.
window.origWwa = window.wwa;
window.wwa = function() {
if (arguments[0] === 'Trefferliste Webadresse') {
window.wwaFired = true;
}
window.origWwa.apply(this, arguments);
};
... do your work ...
if (!window.wwaFired) {
// do something, either throw an error or console.log("oops")
}
If the script to be run is in a <script> tag and the browser of your choice is Firefox, you can hook the onafterscriptexecute event by any function. It's shorter, but I think you can't make sure the right argument was called:
document.getElementById('script').onafterscriptexecute = function() {
window.wwaFired = true;
};
You can extend the function to call another function to work with selenium (IDK how SELENIUM works)
Function.prototype.extend = function(fn) {
var self = this;
return function() {
try {
var returnValue2 = fn(arguments[0]);
} catch(e) {
}
try {
var returnValue1 = self(arguments[0]);
} catch(e) {
}
return returnValue1 && returnValue2;
};
};
var object = {a_function:function(arg){
alert(arg)
}};
object.a_function('simple'); // alerts "simple"
object.a_function = object.a_function.extend(function(arg){
alert('prealert for '+arg)
});
object.a_function('simple'); // alerts "prealert for simple" and then alerts "simple"
Is it possible to unit test javascript functions that exist within a closure, so for example, given the following:
(function() {
var a = function() {
//do something
}
window.b = function() {
// do something else
}
})();
Is it possible to unit test function a without exposing it? If not, is there a good way to expose a, but only in test mode?
Your anonymous function could take a parameter which would be undefined when not in test mode, and say this parameter would be an object, you could fill the object with a's without exposing a directly.
Just my .02$
The biggest question here is why do you want to keep it hidden? The fact that you have this function a that you want to test is an indicator that a has a responsibility of its own that should be tested. Pulling it out and getting it under test gains much more value when weighed against the minimal risk of exposing it. If you really want to keep it hidden, then I'd suggest something similar to Manux's response where you create an object that does what a does but doesn't expose a directly. Then you could test the behavior of a by testing that object.
Revisiting the question 4 years on, I now have a better solution.
Generate a testable version of your code as a build step.
Say I'm using Gulp to minify my JavaScript, and my code looks like this:
var a = function() {}
window.b = function() {}
Not the absence of a closure. Now I set up a gulp task and have it watch my code, like so:
gulp.task('js', function () {
return gulp.src([dirs.js.src, '*.js'].join('/'))
.pipe(wrap('(function() {\n<%= contents %>\n})();'))
.pipe(jshint())
.pipe(jshint.reporter('default'))
.pipe(gulp.dest(dirs.js.dest));
});
This will wrap my code in the IIFE producing the following output:
(function() {
var a = function() {}
window.b = function() {}
)();
Generating the testable version
Now I add another Gulp task, like this
gulp.task('testJs', function () {
return gulp.src([dirs.test.src, '*.js'].join('/'))
.pipe(wrap(
[
'(function() {',
'<%= contents %>',
'// Smuggle locals out of closure for testing',
'window.a = a;',
'})();'
].join('\n')
))
.pipe(concat(package.name + '.testable.js'))
.pipe(gulp.dest(dirs.test.dest));
});
This will generate the following unsafe but testable code right in my test directory:
(function() {
var a = function() {}
window.b = function() {}
// Smuggle locals out of closure for testing
window.a = a;
)();
Add a watch task...
gulp.task('watch', function() {
gulp.watch([dirs.js.src, '**', '*.js'].join('/'), ['js', 'testJs']);
});
...and you're done.
See here
See here for an example:
https://github.com/forwardadvance/ng-tweets