I am learning how to use jsMockito to write perfect code. So, could you give me any idea on how to run callback which is provided to service?
Here is my class:
function MyClass(service) {
this.service = service;
}
MyClass.prototype.doSomething = function() {
this.service.doIt(function() {
console.log("How to run this function while running tests?");
})
}
And here is my test:
var MyClassTest = TestCase("MyClassTest");
MyClassTest.prototype.testMyClass = function() {
this.service = mock(Service);
this.myClass = new MyClass(this.service);
this.myClass.doSomething();
}
So, I need to see the log message:
"How to run this function while running tests?"
Any ideas are welcome.
Finally I have found the solution.
We need to create doItCallback:
function MyClass(service) {
this.service = service;
}
MyClass.prototype.doItCallback = function() {
console.log("How to run this function while running tests?");
}
MyClass.prototype.doSomething = function() {
this.service.doIt(this.doItCallback);
}
Also we need to update the mock:
var MyClassTest = TestCase("MyClassTest");
MyClassTest.prototype.testMyClass = function() {
this.service = mock(Service);
this.myClass = new MyClass(this.service);
var myClass = this.myClass;
when(this.service).doIt().then(function() {
myClass.doItCallback();
});
this.myClass.doSomething();
}
Related
I have a Javascript modular application not using Angular/Backbone.
I am trying to write test case for my startup module but facing issue.
Startup.js:
window.claimStartup = function (options) {
this.options = $.extend({}, this.options, options);
this.cmds = new this.serviceModule(this);
}
getClaimsCategories: function (claimTypeCode) {
var self = this;
// Refresh claim categories
return $.when(self.cmds.getClaimsCategories(claimTypeCode))
.then(function (response) {
return response;
});
},
Service.js:
claimStartup.prototype.serviceModule = function (cfg) {
this.cfg = cfg;
this.init();
}
StartUp.spec.js:
var claimStartUp;
beforeEach(function () {
spyOn(window.claimStartup.prototype, 'serviceModule');
claimStartUp = new window.claimStartup();
});
it("should be able to get categories", function () {
jasmine.spyOn(claimStartUp.cmds, 'getClaimsCategories').andReturn('XYZ');
var categories= claimStartup.getClaimsCategories('ABC');
expect(categories).toEqual('XYZ');
});
I am getting error when populating this.cmds it says serviceModule constructor not defined, actually I need to mock serviceModule when claimStartup is initialised.
Please let me know how can i write test case in this scenario.
I am able to fix this, this might be useful for others.
var claimStartUp;
beforeEach(function () {
var spyService = jasmine.createSpy('serviceModule');
var methodService = window.claimStartup.prototype.serviceModule;
window.claimStartup.prototype.serviceModule = spyService;
var spyUI = jasmine.createSpy('uiModule');
var methodUI = window.claimStartup.prototype.uiModule;
window.claimStartup.prototype.uiModule = spyUI;
claimStartUp = new window.claimStartup();
});
Can I get a little advice on my js modules? I'm good with js, but not quite guru status :) Am I refactoring my modules right?
I've been using the js module pattern like this (rough example, I'm just worried about the structure):
sloppy way?
/* Module Code */
var MapModule = (function ($) {
var $_address;
var $_mapContainer;
function loadApi() {
// do something. maybe load an API?
}
function someInternalMethod() {
// do other things
}
var pub = {};
pub.setAddress = function (address) {
$_address = address;
};
pub.getAddress = function () {
return $_address;
};
pub.initialize = function () {
loadApi();
}
})(jQuery);
// usage
MapModule.initialize();
But that usage seems a little sloppy. I like constructors.
I refactored some modules like this:
Better way?
(function ($) {
this.MapModule = function () {
var $_address;
var $_mapSelector;
var $_mapContainer;
function loadApi() {
// do something. maybe load an API?
}
function someInternalMethod() {
$_mapContainer = $($_mapSelector);
// do stuff with the jQ object.
}
var pub = {};
pub.setAddress = function (address) {
$_address = address;
};
pub.getAddress = function () {
return $_address;
};
pub.initialize = function (selector) {
$_mapSelector = selector;
loadApi();
}
}
})(jQuery);
var map = new MapModule();
map.initialize('#mapcontainer');
That usage seems a lot cleaner to me, and it works just fine, but am I going about it properly?
Taking it another step
Say this module does some stuff with a div that wraps Google Maps and jQuery functionality: Any tips on turning that into a jQ plugin so I can use it with a signature like var map = $('mapcontainer').mapModule();
Thanks!
I have modified your snippet and have actually implemented javascript revealing module pattern which gives the opportunity to implement public & private functions using closure.
Hope this will be helpful:
/* Module Code */
var MapModule = (function (module, $, global) {
var $_address;
var $_mapContainer;
// Public functions
function _loadApi() {
// Do something, maybe load an API?
}
function _someInternalMethod() {
// Do other things.
}
function _initialize = function () {
_loadApi();
}
// Private functions
function _setAddress = function (address) {
$_address = address;
};
function _getAddress = function () {
return $_address;
};
$.extend(module, {
loadApi: _loadApi,
someInternalMethod: _someInternalMethod,
initialize: _initialize
});
return module;
})(MapModule || {},this.jQuery, this);
// Usage
MapModule.initialize();
JSFiddle
Just came across this and thought I'd share my approach...
///////////////////////////////
// Module Code
///////////////////////////////
var ExampleModule = (function()
{
////////////////////////////
// Private Properties
////////////////////////////
var whatever = {
data: 'somedata';
};
////////////////////////////
// Private functions
////////////////////////////
function _init()
{
_loadApi();
_bindToUIEvents();
}
function _loadApi()
{
// load an api
}
function _bindToUIEvents()
{
$('#something').on('click', function(){
// Do something cool
});
}
function _getWhatever()
{
return whatever;
}
//////////////////////
// Public API
//////////////////////
return{
init: _init(),
getWhatever: function()
{
return _getWhatever();
}
};
})();
// Usage
ExampleModule.init;
I have JavaScript class which have huge functions which are very difficult to maintain.
The 2 public functions are called at start and then on click. I want to create private functions inside these public functions say break into into some private functions scope to these public methods.
var searchResultView;
var SearchResultView = function () {
me = this;
this.init = function () {
// huge code
}
this.Search = function () {
// huge code
}
}
jQuery(function () {
searchResultView = new SearchResultView();
searchResultView.init();
searchResultView.Search();
}
What will best way to achieve this. I tried to use below approach but i think this nested function will not work well.
var searchResultView;
function searchResultView() {
me = this;
this.init = function () {
var declareControls = function () {}
var addEvents = function () {}
var fillControls = function () {}
declareControls();
addEvents();
fillControls();
}
this.Search = function () {
var validateAndCreateCriteria = function () {
if (!validateAandGetLocation()) {
alert("invalid location");
return false;
}
if (!validateAandGetCategory()) {
alert("choose search type");
return false;
}
var validateAandGetLocation = function () {}
var validateAandGetCategory = function () {}
}
validateAndCreateCriteria();
}
}
jQuery(function () {
searchResultView = new searchResultView();
searchResultView.init();
});
If I understood correctly, you should have the functions something like this:
var foo = (function() {
var privateBar = function() { // private function
},
privatefooBar = function() { // private function
};
return {
publicFoo : function() { //public function
/* use privateBar and privatefooBar functions here */
}
};
})();
Later you can access publicFoo function by using
foo.publicFoo();
But you can't access the inside functions which are privateBar() and privatefooBar() directly because they are private functions.
Updated Fiddle
Breaking up the function is easy:
function f(..) {
// many lines here
return ret_f;
}
if equivalent to
function f {
function f1(..) {
// not so many lines here
}
function f2(..) {
// not so many lines here
}
var ret_f1 = f1(..);
var ret_f2 = f2(..);
// calculate ret_f from ret_f1 and ret_f2
return ret_f;
}
or if you prefer this style using anonymous functions
function f {
var f1 = function(..) {
// not so many lines here
};
var f2 = function(..) {
// not so many lines here
};
var ret_f1 = f1(..);
var ret_f2 = f2(..);
// calculate ret_f from ret_f1 and ret_f2
return ret_f;
}
I fear however your real question is specific to your existing code and is about what useful smaller functions to extract there and how to combine them.
For this one would need to have your full code and understand it. That might be a bit much for this QA format.
I am trying to write a small javascript library as shown below. What I really want is when I call
console.log(tnd().pv);
it should output same number and not generate new number everytime. I know the issue is it calls Math.random everytime I console log. But how can I do so that it outputs same number?
(function () {
var tnd = function() {
return new tnlib();
};
var tnlib = function() {
this.version = function(){
console.log('1.0');
};
this.pv = Math.random()*10000000000000000;
};
if(!window.tnd) {
window.tnd = tnd;
}
})();
Don't execute Math.random() on each invocation of tnlib, but as a static variable:
(function () {
function tnd() {
return new tnlib();
}
function tnlib() {
}
tnlib.prototype.version = function(){
console.log('1.0');
};
tnlib.prototype.pv = Math.random()*10000000000000000;
if (!window.tnd) {
window.tnd = tnd;
}
}());
(or, if you really need to make pv an instance property):
var staticPv = Math.random()*10000000000000000;
function tnlib() {
this.pv = staticPv;
…
}
In the following code, I want to be able to call bindClickEvents() like so:
App.Utils.Modal.bindClickEvents();
However, I don't understand the syntax necessary to do this.
Current code:
var App = new Object;
App.Modal = {
bindClickEvents: function() {
return $('a.alert-modal').click(function(e) {
return console.log('Alert Callback');
});
}
};
$(document).ready(function() {
return App.Modal.bindClickEvents();
});
You can do it in one go:
var App = {
Modal : {
bindClickEvents : function () {/* ... */}
}
}
or if you want to break that up to separate steps:
var App = {};
App.Modal = {};
Modal.bindClickEvents = function () {/* ... */};
BTW, in reference to your original question title, this is not object chaining. This is object composition. Object chaining is being able to call methods in an object multiple times in a single statement.
Is this what you're trying to do?
var App = {};
App.Utils = {};
App.Utils.Modal = {
bindClickEvents: function() {
return $('a.alert-modal').click(function(e) {
return console.log('Alert Callback');
});
}
};
$(document).ready(function() {
return App.Utils.Modal.bindClickEvents();
});
Prefer the object literal syntax to the Object constructor; some authors go so far as to call the latter an anti-pattern
Here's the simplest way to set up App.Utils.Modal.bindClickEvents();
var App = {
Utils: {
Modal: {
bindClickEvents: function() {
return $('a.alert-modal').click(function(e) {
return console.log('Alert Callback');
});
}
}
}
};
Or you can piece it together one step at a time:
var App = {};
App.Utils = {};
App.Utils.Modal = {};
App.Utils.Modal.bindClickEvents = function() {
return $('a.alert-modal').click(function(e) {
return console.log('Alert Callback');
});
};