Say I have a module with two functions with one depending on the other:
// example.js
function A() {
return "hello";
}
function B() {
return A();
}
module.exports.B = B;
Can I use rewire to mock the call to A() in B()?
// example.test.js
var assert = require('chai').assert,
rewire = require('rewire'),
example = rewire('./example.js');
example.__set__({
A: function( return 'goodbye';),
});
describe('test B in example.js', function() {
it('should return "goodbye"', function() {
assert.strictEqual(example.B(), 'goodbye');
});
});
Yes, this does work. I'm not sure what solved the problem exactly. Previously I was exporting the dependent function as part of a function prototype (e.g. function.prototype.dependentFunction = function() { };) and somehow this was messing with rewire. I redefined my function by declaring/defining it first and then attaching it to the model:
function dependentFunction() { ... }
exportedObject.prototype.dependentFunction = dependentFunction();
Doing this fixed my problems.
Related
let's say i have a function
Func a() {
//Do Something
let c = b();
return c;
}
I want to test the function a and mock b() and in the mock want to assign c.
Sinon.Stub(Test,"b").returns("DummyValue");
c should be assigned DummyValue.
How can I do that?
describe("a", () => {
let a = a();
//mock b();
action = execute(a);
expect(action).should.return.("DummyValue");
})
When we have 2 functions in the same file and want to stub one of them and test the other.
For example,:
Test: tests.js
let ComputeSumStub = sinon.stub(OfflineLoader, "ComputeSum");
const ans = function ()
{
return 10;
};
ComputeSumStub.returns(ans);
const actualValue: number = OfflineLoader.sum();
expect(actualValue).to.be.equal(10);
Dev: foo.js
function sum(): number
{
return ComputeSum(8, 9);
}
function ComputeSum(a: number, b: number): number
{
return a + b;
}
We cannot do that, because after compilation the functions are exported with different signatures, with full name and while stubbing we stub the global function but while calling it from within the other function, we call the local function, hence it doesn’t work.
There is a workaround to do that.
foo.js
const factory = {
a,
b,
}
function a() {
return 2;
}
function b() {
return factory.a();
}
module.exports = factory;
test.js
const ser = require('./foo');
const sinon = require('sinon');
const aStub = sinon.stub(ser, 'a').returns('mocked return');
console.log(ser.b());
console.log(aStub.callCount);
Ref: Stubbing method in same file using Sinon
You can stub function only
if you pass it as parameter ans fake it with test doubles library like sinon
or if it is dependency (loaded via import or require). In such case you can use proxyquire to pass in your fake b function for module under test. Function itself can be faked by sinon or other test doubles library.
In this case a sinon stub is more appropriate then a mock
When to use mocks vs stubs?
The rule of thumb is: if you wouldn’t add an assertion for some
specific call, don’t mock it. Use a stub instead.
Our assertion in the test is not on a specific call of function a i.e 1st or 3rd call but on all calls.
We can tel this because we have programmed our stub to always return the same result regardless of the way in which it is being called (arguments, or number of calls).
Pass a sinon stub function as an argument to function a.
Function a(b) {
const c = b();
return c;
}
test.js
require("sinon")
describe("a", () => {
const stub = sinon.stub();
stub.returns("DummyValue");
expect(a(stub)).to.eql.("DummyValue");
})
Note that we can use const for these variable declarations as they are never being reassigned.
I've checked a lot of codes and I've saw a lot of people doing
module.exports = (function(){
return {
functionA: function() {
}
},
functionB: function() {
}
};
})();
so, why not just do
module.exports = {
functionA: function() {
},
functionB: function() {
}
};
Thanks!
Your first example allows you to hide variables within its own closure scope that can be shared with your return object's methods. The For example, if you did the following...
var foo = (function(){
var x = 2;
return {
addToTwo: function(y){
return x + y;
},
subtractFromTwo: function(y){
return x - y;
}
}
};
The above example shows that the x variable is protected and shared between addToTwo and subtractFromTwo. The second example only will allow you to make x as part of the object without the same protection.
module.exports = {
x: 3,
functionA: function() {
return this.x;
},
};
x can be altered in this example.
Those are exactly the same. It's a stylistic decision.
According to the Node.js docs:
Variables local to the module will be private, as though the module was wrapped in a function.
You could also do it this way:
module.exports.functionA = function() {
};
module.exports.functionB = function() {
};
Or:
// either method for creating a function works
function functionA () {}
var functionB = function () {}
module.exports = {
functionA : functionA,
functionB : functionB
};
One of the greatest advantages of directly invoked functions is the use of closures which cannot be obtianed in a separate manner, so literally they are not the same.
I have the below code:
filtersManager = (function ($) {
var that = this;
function configure() {
// some work
return that;
};
function process() {
// some work
return that;
}
return {
// public functions
configure: configure,
process: process
};
}(jQuery));
but when it's called using the below it fails:
filtersManager.configure().process();
Error: Object doesn't support property or method 'process'
whereas the below works:
filtersManager.configure();
filtersManager.process();
You are returning the wrong thing (this in a plain function invocation is the global object). You want to return the object that you originally created, which I will call the interface.
filtersManager = (function ($) {
var interface = {
// public functions
configure: configure,
process: process
};
function configure() {
// some work
return interface;
};
function process() {
// some work
return interface;
}
return interface;
}(jQuery));
If you're wondering why I can reference the functions defined below, it's due to hoisting.
Immediate function is executed in global object (window) context. Try something similar to this:
filtersManager = (function ($) {
var that = {};
that.configure = function() {
// some work
return that;
};
that.process = function() {
// some work
return that;
}
return that;
}(jQuery));
UPD. Based on comments
Constructor pattern seems to fit your need better:
var FiltersManager = (function($) {
function FiltersManager() {}
FiltersManager.prototype = {
configure: function() {
console.log('configure');
return this;
},
process: function() {
console.log('process');
return this;
}
}
return FiltersManager;
}(jQuery));
new FiltersManager().configure().process();
As to continue what others have said , I think you confused with the function constructor syntax which would work , similar to what you've said ;
var G=function g()
{
this.configure =function (){return this;}
this.process =function (){return this;}
};
var _= new G();
console.log(_.configure().process())
If you wanted to re-use the functions on other objects too, you could do it like this
filtersManager = function ($) {
function configure() {
// some work
return this;
};
function process() {
// some work
return this;
}
return {
// public functions
configure: configure,
process: process
};
}(jQuery);
(OTOH, if you wanted to create aliases to them, you would then have to bind them to the object)
Or if configure and process are quite short, simple functions :
filtersManager = (function ($) {
return {
// public functions
configure: function () {
// some work
return this;
},
process: function () {
// some work
return this;
}
};
}(jQuery));
I want to make file with four or five exports function.
exports.a = function() {
// some code
};
exports.b = function() {
// need to call function a
};
and I need from second (in this case function b to call function a) to call first exported function, but it ignores call and never enter in first function ( in this case function a).
How to call first exported function from second exported ?
You can do it like this:
var a = exports.a = function() {
// some code
};
exports.b = function() {
a();
};
Or you could use exports.a() in the second function, but this would mean looking up the field a in exports each time. Using var a = ... is faster.
A pattern I often see is something like:
var a = function() {
// ...
};
var b = function() {
var c = a();
// ...
return c; // or whatever
};
// Now decide what declared variables are being exported.
module.exports = {
a: a,
b: b
};
Declare everything you want to use, then export what should be public as the last thing.
Let's say I have the namespace,
var Namespace = {
A : function() {
alert('Hello!');
},
B : function() {
// Call A() from here, do other stuff
}
}
In this namespace, I intend for A to be a helper function to B. That is to say, A() will never be called outside the namespace. It will only be called by the functions within the namespace.
What's the best way to address the issue of a local/helper function within a namespace? The way I see it there are two possibilities:
// Method #1
var Namespace = {
A: function() {
alert('Method #1');
},
B : function() {
Namespace.A();
}
}
Namespace.B();
// Method #2
function Namespace2() {
var A = function() {
alert('Method #2');
};
this.B = function() {
A();
}
}
var ns2 = new Namespace2();
ns2.B();
In the first method, it is ugly and awkard to type Namespace.A() (repeatedly) in every function within the namespace. This leads me to prefer Method #2. But I was curious what was the best practice here.
I recommend placing the "namespace" inside a function scope. Everything not explicitly public will be naturally private:
var Namespace = (function() {
var self = {};
// Private
var A = function() {
...
};
// Public
self.B = function() {
A();
}
return self;
}());
Namespace.B(); // Works
Namespace.A(); // Doesn't work
You can call it using this statement
this.A();
Well you can event use a third option where the Namespace is created in it's own scope:
var Namespace = (function(){
var A = function() {
alert('scoped method');
};
function Namespace() {
var A1 = function() {
alert('Namespace "private" method');
};
Namespace.prototype.B1 = function(){
A(); //will run
A1(); //will run with no errors
};
};
Namespace.prototype.B = function(){
A(); //will run
A1(); //ERROR!
};
return Namespace;
})();
If you only intend to use A inside B, why not define it inside B?
var Namespace = {
B: function() {
var A = function() {
...
}
A();
}
};
Namespace.B();
var Namespace = {
A : function() {
alert('Hello!');
},
B : function() {
Namespace.A();
},
}
note the Semi-colon at the end