Is there a way to test not-exported functions with Jest using TypeScript? I've seen SO answers recommending some libraries like rewire
but it seems they are not really TypeScript compatible yet. The other way would be to export these private functions as well, but I think there must be a solution without exporting just for testing purposes.
The setup is the following. There are two functions, one is exported, one is not.
export function publicFunction() {
privateFunction();
}
function privateFunction() {
// Whatever it does
}
In my unit-tests there are two cases I wish to solve. Testing the privateFunction
itself and mocking it for publicFunction
tests.
I am using ts-jest to compile the typescript files when testing. The jest.config.json looks like
{
"transform": {
"^.+\\.(t|j)sx?$": "ts-jest"
},
"testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.(tsx?)$",
"moduleFileExtensions": ["ts", "tsx", "js", "jsx", "json", "node"],
"testEnvironment": "node",
"globals": {
"ts-jest": {
"tsConfig": "test/tsconfig.spec.json"
}
}
}
I am familiar with jest.fn()
but I don't know how to overwrite or extract the private function. And an unit-test would be something like
import { publicFunction } from '../src';
describe('publicFunction', () => {
it('should call "privateFunction" once', () => {
// Overwrite privateFunction with jest.fn();
publicFunction();
expect(...).toHaveBeenCalled(1);
});
});
Or to test the private function, for which importing it is not possible.
import { privateFunction } from '../src/index'
describe('privateFunction', () => {
it(...
});
Any ideas or suggestions? Thanks!
For testing non-exported functions with JEST and Typescript I have used Rewire. With little problem that we have to provide rewire a path of the TS build folder and not the .ts file path.
Following is my directory structure:
app
|---dist
|---controllers
|---api.js
src
|---controllers
|---api.ts
|---api.spec.ts
So for rewire I have to provide path of ./dist/controllers/api
and not ./src/controllers/api
Here is my sample code:
import rewire from "rewire";
const api = rewire('../../dist/controllers/api'); // path to TS build folder
describe("API Controller", () => {
describe('Fetch Route Params', () => {
let fetchRouteParams: (url: string) => string;
beforeEach(() => {
fetchRouteParams = api.__get__('fetchRouteParams'); // non-exported function
});
it('should fetch route params from url', () => {
const url = "https://example.com/foo/api/products";
expect(fetchRouteParams(url)).toEqual('foo/api/products');
});
it('should not fetch route params from url', () => {
const url = "";
expect(fetchRouteParams(url)).toEqual('');
});
});
});
Even I have not came across some better solution apart from going with rewire
. But it works for testing non-exported functions.
NPM Packages I have used:
npm i -D rewire
npm i -D @types/rewire
Hope it helps, Thanks.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With