clear encapsulated value in imported module - Jest js - javascript

Let's say I'm importing to Jest module like:
let var;
export const getVar = () => {
if(var == null) {
var = Date.now()
}
return var;
}
I am trying to make unit tests for this module, however, on every unit test I have to reset the "var" value. I've tried to redefine the module using require on "beforeEach" method but it does not work. Does anyone know how to reset encapsulated values like this?

Using old require syntax and resetModules
foo.js
let foo;
const getFoo = () => {
if (!foo) {
foo = "foo";
} else {
foo = "bar";
}
return foo;
};
module.exports = { getFoo };
foo.test.js
beforeEach(() => jest.resetModules());
test("first", () => {
const { getFoo } = require("./foo");
expect(getFoo()).toBe("foo");
});
test("second", () => {
const { getFoo } = require("./foo");
expect(getFoo()).toBe("foo");
});
Using dynamic import and resetModules
foo.js
let foo;
export const getFoo = () => {
if (!foo) {
foo = "foo";
} else {
foo = "bar";
}
return foo;
};
foo.test.js
import { jest } from "#jest/globals";
beforeEach(async () => {
jest.resetModules();
});
test("first", async () => {
const { getFoo } = await import("./foo.js");
expect(getFoo()).toBe("foo");
});
test("second", async () => {
const { getFoo } = await import("./foo.js");
expect(getFoo()).toBe("foo");
});

Related

Mock a function and used it as UUT with Jest in JS

I want to test one function from exported object in one describe and mock it in another function from the same exported object since the second function is using the first function.
// funcs.js
const func1 = () => {
return true;
};
const func2 = () => {
const bool = func1();
if (bool) {
// do something
} else {
// do else
}
};
export const funcs = {func1, func2};
// funcs.spec.js
const {funcs as uut} from './funcs';
describe('unit', () => {
describe('func 1', () => {
test('', () => {
const bool = uut.func1();
expect(bool).toBeTruthy();
});
});
describe('func 2', () => {
test('', () => {
jest.mock(uut.func1).mockReturnValue(false);
uut.func2();
// rest of test
});
});
});
I tried using jest.requireActual but did not work. What is the best approach for this if even possible?

mocking private methods to test an exported method fails in jest

I'm having an actual class like this
my-file.js
const methodA = () => { return 'output-from-methodA'; }
const methodB = () => { const b = methodA(); b.c = "out-put bind"; return b; }
module.exports = {
methodB
}
my-file.test.js
const { methodA, methodB } = require('./my-file.js');
describe('methodB testing', () => {
it('should call methodA', () => {
methodB();
expect(methodA).toHaveBeenCalled()
}
});
here methodA is private method, so it is not explicit to the test file, then how i ensure it is called or not in the test files
There is no way to test the private function, only the alternative way found is to test the outputs like
const { methodA, methodB } = require('./my-file.js');
describe('methodB testing', () => {
it('should call methodA', () => {
const result = methodB();
expect(result.b.c).toBe("out-put bind")
}
});

Jest mocking module that exports a class and functions

I have a module that exports a class and 2 functions and that module is imported into a file that is being tested.
someFile.js
const {theclass, thefunction} = require("theModule");
const getSomeFileData = () => {
let obj = new theclass();
//some logic
return obj.getData();
}
In the test file, I want to mock the module "theModule" and return a known value when the function obj.getData() is called. How would I go about mocking this module("theModule") when testing file "someFile.js"?
Edit:
.spec.ts
import { someFunction } from './index-test';
jest.mock('lodash', () => {
return {
uniqueId: () => 2,
};
});
describe('', () => {
it('', () => {
expect(someFunction()).toBe(2);
});
});
index-test.ts
import { uniqueId } from 'lodash';
export const someFunction = () => {
return uniqueId();
};

How to use Jasmine.js spy on a required function

I have this code (Node.js):
File: utils.js
// utils.js
const foo = () => {
// ....
}
const bar = () => {
// ....
}
module.exports = { foo, bar }
File: myModule.js
// myModule.js
const {
foo,
bar
} = require('./utils');
const bizz = () => {
let fooResult = foo()
return bar(fooResult)
}
module.exports = { bizz }
File: myModule.spec.js
// myModule.spec.js
const { bizz } = require('./myModule');
describe('myModule', () => {
it('bizz should return bla bla bla', () => {
let foo = jasmine.createSpy('foo').and.returnValue(true)
let bar = jasmine.createSpy('bar').and.callFake((data) => {
expect(date).toBeTrue();
return 'fake-data'
})
expect(bizz()).toBe('fake-data')
})
})
I'm trying to test bizz using spies on foo and bar functions but it's not working well.
Can anyone explain to me how to create spies on these functions with the purpose to test bizz??
Yes, it is possible.
You just need to require utils to spyOn first, then require myModule. The following test will pass.
const utils = require('./utils');
// myModule.spec.js
describe('myModule', () => {
it('bizz should return bla bla bla', () => {
const fooSpy = spyOn(utils, 'foo').and.returnValue(true);
const barSpy = spyOn(utils, 'bar').and.callFake(data => {
expect(data).toBeTrue();
return 'fake-data';
});
const { bizz } = require('./myModule'); // Import myModule after you added the spyOn
expect(bizz()).toBe('fake-data');
expect(fooSpy).toHaveBeenCalled();
expect(barSpy).toHaveBeenCalled();
});
});
Hope it helps
Seems like it's not possible. https://github.com/mjackson/expect/issues/169

Unit testing an inner function?

I have a function that has inner functions, for my unit test, I only want to test the functionality of the inner function, but when I export the function and call the inner function, npm tests returns an error.
In my main.js:
mainFunction = () => {
functionToBeTested = () => {
// some code
}
}
module.exports = {mainFunction: mainFunction}
In my test.js
const chai = require("chai");
const assert = require("chai").assert;
const mainFunction = require("./main");
describe ("test", () => {
it("returns results", () => {
let result = mainfunction.functionToBeTested(args);
//equal code
});
})
But when I run npm test, it says:
mainfunction.functionToBeTested is not a function.
What am I doing wrong?
If you want to chain your functions you can try something like that.
main.js
const mainFunction = () => {
const functionToBeTested = () => {
return "I got it";
}
return { functionToBeTested };
}
module.exports = { mainFunction };
test.js
const chai = require("chai");
const assert = require("chai").assert;
const mainFunction = require("./main");
const mf = mainFunction();
describe ("test", () => {
it("returns results", () => {
let result = mf.functionToBeTested(args);
//equal code
});
});
Actually, you can't call a function declare inside another function that way. A solution would be to declare functionToBeTested outside mainFunction, then call it :
main.js
const functionToBeTested = () => {
// some code
};
const mainFunction = () => {
functionToBeTested();
};
module.exports = { mainFunction, functionToBeTested }
test.js
const chai = require("chai");
const assert = require("chai").assert;
const { mainFunction, functionToBeTested } = require("./main");
describe ("test", () => {
it("tests mainFunction", () => {
let main = mainfunction(args);
...
});
it("tests functionToBeTested"), () => {
let tested = functionToBeTested(args);
...
});
})
It is because only mainFunction() is exported and not the functionToBeTested(), outside this module JS doesn't knows about the existence of the functionToBeTested().
I will recommend you to move functionToBeTested separated and export that as well or have a helper method for calling it.

Categories