Jasmine : Spying on a function call of another module - node.js

I have the following code structure :
const finalCall = require('./final.js');
function Func(){
this.process = {
initCall: function(params, callback){
let proParams;
//processing...
return finalCall(proParams, callback);
}
}
}
Now I need to test if my initCall function correctly processes the params and makes call to finalCall. I need to know how do I create a spy on my finalCall function, so when it gets called, I can track the proParams.
I have tried something like :
const func = new Func();
let proParams = null;
spyOn(func.process.initCall, "finalCall").and.callFake(function(pParams, callback){
proParams = pParams;
});
let params = { };
func.process.initCall(params, null);
expect(func.process.initCall.finalCall).toHaveBeenCalled();
expect(proParams).toEqual('...');
I am missing on what object I can access finalCall, or if there is another way to do so. Thanks in advance.

Finally I found a workaround to my problem. I created a prototype of the function finalCall() in my constructor Const, and put a spyOn on its object.
Solution
Main module:
const finalCall = require('./final.js');
function Func(){
const self = this;
this.process = {
initCall: function(params, callback){
let proParams;
//processing...
return self.finalCall(proParams, callback);
}
}
}
Func.prototype = finalCall;
and in my Spec file:
const func = new Func();
let proParams = null;
spyOn(const, finalCall);
let params = { };
func.process.initCall(params, null);
expect(func.finalCall).toHaveBeenCalled();

Related

nodejs function().anotherFunction() how they do it?

I install a library/module but I am curious how they do it
const modules = require('abc');
const app = new modules('123');
const client = app.f1('abcdef').f2('ghi');
console.log(client.to());
const client2 = app.f1('1111111').f2('2222');
console.log(client2.to());
console.log(client.to());
result is 123:abcdef-ghi
result is 123:1111111-2222
result is 123:abcdef-ghi
how they did it?
i want to create that example lib/module
please give me sample code
Depending on your exact requirements, something like this seems to work:
let state = Symbol("private")
class App {
constructor(arg) {
this[state] = arg
}
f1 = arg => new App(this[state] + ":" + arg)
f2 = arg => new App(this[state] + "-" + arg)
to = () => this[state]
}
Here each of the chainable method returns a new instance of the class, each keeping the temporary result as a local state. The to() method returns that state.
This is what I use for doing function().anotherFunction()
function func() {
console.log("ran func")
return {
"anotherFunc": function () {
console.log("ran another func")
}
}
}
func().anotherFunc()
You can also just return a object
const returnData = {
"anotherFunc": function () {
console.log("ran another func")
}
}
function func() {
console.log("ran func")
return returnData
}
func().anotherFunc()
Example of use:
function word1(in_1) {
return {
"word2": function (in_2) {
console.log(`Inputs: ${in_1} ${in_2}`)
}
}
}
word1("Hello").word2("World")
// Expected output: Inputs: Hello World

passing function to a class in nodejs

I have a function that I need to pass to a class I have defined in nodeJs.
The use case scenario is I want to give the implementer of the class the control of what to do with the data received from createCall function. I don't mind if the method becomes a member function of the class. Any help would be appreciated.
//Function to pass. Defined by the person using the class in their project.
var someFunction = function(data){
console.log(data)
}
//And I have a class i.e. the library.
class A {
constructor(user, handler) {
this.user = user;
this.notificationHandler = handler;
}
createCall(){
var result = new Promise (function(resolve,reject) {
resolve(callApi());
});
//doesn't work. Keeps saying notificationHandler is not a function
result.then(function(resp) {
this.notificationHandler(resp);
}) ;
//I want to pass this resp back to the function I had passed in the
// constructor.
//How do I achieve this.
}
callApi(){ ...somecode... }
}
// The user creates an object of the class like this
var obj = new A("abc#gmail.com", someFunction);
obj.createCall(); // This call should execute the logic inside someFunction after the resp is received.
Arrow functions (if your Node version supports them) are convenient here:
class A {
constructor(user, handler) {
this.user = user;
this.notificationHandler = handler;
}
createCall() {
var result = new Promise(resolve => {
// we're fine here, `this` is the current A instance
resolve(this.callApi());
});
result.then(resp => {
this.notificationHandler(resp);
});
}
callApi() {
// Some code here...
}
}
Inside arrow functions, this refers to the context that defined such functions, in our case the current instance of A. The old school way (ECMA 5) would be:
createCall() {
// save current instance in a variable for further use
// inside callback functions
var self = this;
var result = new Promise(function(resolve) {
// here `this` is completely irrelevant;
// we need to use `self`
resolve(self.callApi());
});
result.then(function(resp) {
self.notificationHandler(resp);
});
}
Check here for details: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions#No_separate_this

NodeJs giving me a Object #<Object> has no method

I have a class along with its helper class defined:
function ClassA(){
this.results_array = [];
this.counter = 0;
this.requestCB = function(err, response, body){
if(err){
console.log(err);
}
else{
this.counter++;
var helper = new ClassAHelper(body);
this.results_array.concat(helper.parse());
}
};
};
function ClassAHelper(body){
this._body = body;
this.result_partial_array = [];
this.parse = function(){
var temp = this.parseInfo();
this.result_partial_array.push(temp);
return this.result_partial_array;
};
this.parseInfo = function(){
var info;
//Get some info from this._body
return info
};
};
NodeJS gives me the following error:
TypeError: Object #<Object> has no method 'parseInfo'
I cannot figure out why I can't call this.parseInfo() from inside ClassAHelper's parse method.
If anyone can explain a possible solution. Or at least, what is the problem? I tried reordering the function declarations, and some other ideas, but to no avail.
P.S. I tried simplifying the code for stackoverflow. Hepefully it still makes sense :)
P.P.S This is my first stackoverflow question. Hopefully I did everything right. :)
Here's a simplified example which works:
function A() {
this.x = function (){
return this.y();
};
this.y = function (){
return "Returned from y()";
};
}
var a = new A();
a.x();
Notice the use of new and calling the method with a.x().
How are you creating an instance of your functions and calling parse in ClassAHelper?
Is it anything like these:
var a = A();
a.x();
// Or
A.x()
this is scoped to the function it is inside. So, when you do this.parse=function(){, there is a new this. To keep ClassAHelper's this, you have to pass it in or reference it inside the anonymous function you made. The following example assigns this to a variable outside of the function and references it inside the function:
function ClassAHelper(body){
this._body = body;
this.result_partial_array = [];
var self = this;
this.parse = function(){
var temp = self.parseInfo();
self.result_partial_array.push(temp);
return self.result_partial_array;
};
this.parseInfo = function(){
var info;
//Get some info from this._body
return info;
};
};
Further reading and other ways of doing it:
Why do you need to invoke an anonymous function on the same line?

Passing function to other prototype

I have below code
http://jsfiddle.net/qhoc/SashU/1/
var Callback = function(op) {
this.callback = op.callback;
}
var Test = function (op) {
for (var option in op) {
if (!this[option]) this[option] = op[option];
}
}
Test.prototype.init = function(bb) {
console.log('aa = ' + this.aa);
console.log('bb = ' + bb);
if (bb < 3) {
this.init(bb + 1);
} else {
this.callback;
}
}
var finalCallback = function() {
console.log('this is finalCallback');
}
var myCallback = new Callback({
callback: finalCallback
});
var myTest = new Test({
aa: 1,
callback: myCallback
});
myTest.init(1);
Line 19 didn't print 'this is finalCallback' AT ALL because this.callback; got executed but it doesn't point to a function. But the below works:
myTest.init(1);
myCallback.callback();
I guess when passing myCallback to myTest, it didn't pass finalCallback??
Can someone help to explain this behavior and how to fix it?
seems you want to make this (use op.callback as function ):
var Callback = function (op) {
this.callback = op.callback;
return this.callback;
};
and functions should be invoked with ()
} else {
this.callback();
}
http://jsfiddle.net/oceog/SashU/3/
this is example where it can be used
this works:
var myTest = new Test({
aa: 1,
callback: myCallback.callback()
});
I assume this is the bit you mean. If not, please clarify what is not printing.
this doesn't work, because it is only a reference - an assignment.
callback: myCallback
this is what executes it ()
so:
callback: myCallback.callback;
then:
this.callback();
I apologize if I am not succinct enough. I hope I am understanding what you are asking.
As has been pointed out, you're not even trying to invoke this.callback on line 19. Invoke it with parentheses.
Even then, it doesn't work. When you do var myTest = new Test({
aa: 1,
callback: myCallback
});, myCallBack isn't a function; it's an object with a property callback. Change line 19's this.callback to this.callback.callback() to invoke that function. One line 19, this.callback is an instance of Callback—an object with a property callback that is a function.
http://jsfiddle.net/trevordixon/SashU/4/ shows a working example.

Node.js Inheritance

I have inherited a class from another JS, and added few prototype function over Parent functions. When i create a new instance of child, i want to call the constructor of parent. Please suggest a way.
Parent
function Parent() { .. }
Parent.prototype.fn1 = function(){};
exports.create = function() {
return (new Parent());
};
Child
var parent = require('parent');
Child.prototype = frisby.create();
function Child() { .. }
Child.prototype.fn2 = function(){};
exports.create = function() {
return (new Child());
};
You can use module util. Look simple example:
var util = require('util');
function Parent(foo) {
console.log('Constructor: -> foo: ' + foo);
}
Parent.prototype.init = function (bar) {
console.log('Init: Parent -> bar: ' + bar);
};
function Child(foo) {
Child.super_.apply(this, arguments);
console.log('Constructor: Child');
}
util.inherits(Child, Parent);
Child.prototype.init = function () {
Child.super_.prototype.init.apply(this, arguments);
console.log('Init: Child');
};
var ch = new Child('it`s foo!');
ch.init('it`s init!');
First of all, do not export create method, export constructor (Child, Parent). Then you will be able to call parent's constructor on child:
var c = new Child;
Parent.apply(c);
About inheritance. In node you can use util.inherits method, which will setup inheritance and setup link to superclass. If you don't need link to superclass or just want to inherit manually, use proto:
Child.prototype.__proto__ = Parent.prototype;
Parent (parent.js)
function Parent() {
}
Parent.prototype.fn1 = function() {}
exports.Parent = Parent;
Child
var Parent = require('parent').Parent,
util = require('util');
function Child() {
Parent.constructor.apply(this);
}
util.inherits(Child, Parent);
Child.prototype.fn2 = function() {}

Resources