Test function which reads from `json` file - javascript

I have a util file, which imports and checks given sectionUUID has a video in the json file.
import multipleVideos from '../data/videos.json'
function hasSectionMultipleVideos (sectionUUID) {
return multipleVideos.videos.some(({ fields }) => {
return fields.sectionUUID === sectionUUID
})
}
The problem is when I try to test this function(util.test.js), since it doesn't accept multipleVideos data read from the json as an input, how can I test this in jest, by giving my own multiple videos data.

Here is the unit test solution:
index.ts:
import multipleVideos from './videos.json';
function hasSectionMultipleVideos(sectionUUID) {
return multipleVideos.videos.some(({ fields }) => {
return fields.sectionUUID === sectionUUID;
});
}
export { hasSectionMultipleVideos };
index.test.ts:
import { hasSectionMultipleVideos } from './';
describe('61259592', () => {
it('should pass', () => {
const sectionUUID = 1;
const actual = hasSectionMultipleVideos(sectionUUID);
expect(actual).toBeTruthy();
});
});
videos.json:
{
"videos": [
{
"fields": { "sectionUUID": 1 }
},
{
"fields": { "sectionUUID": 2 }
},
{
"fields": { "sectionUUID": 3 }
}
]
}
unit test results with 100% coverage:
PASS stackoverflow/61259592/index.test.ts (13.22s)
61259592
✓ should pass (3ms)
----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files | 100 | 100 | 100 | 100 |
index.ts | 100 | 100 | 100 | 100 |
----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 15.07s
source code: https://github.com/mrdulin/react-apollo-graphql-starter-kit/tree/master/stackoverflow/61259592

Related

How to mock and set function argument correctly in jest mock

I would like to test my mocking by following jest script.I intended to mock exec in returnvalueirohaResponse but , when I run following test,IrohaTransactionExec().exec("testArg1","testArg2") was executed and not returned irohaResponse
What is the wrong point of that? and How can I mock correctly? Thanks
it("mocking test",async ()=>{
const irohaResponse= registered;
const iroha = new IrohaTransactionExec()
const mockfunc = jest.spyOn(iroha,"exec")
mockfunc.mockReturnValue(Promise.resolve(irohaResponse))
expect(await new IrohaTransactionExec().exec("testArg1","testArg2")).toEqual(irohaResponse)
},10000)
import { IrohaClientBuilder,IrohaRequestParam } from "#post-pricing/library/lib/src/utility"
import { IrohaInterface } from "#post-pricing/library/lib/src/const/irohaApi"
export class IrohaTransactionExec {
private irohaClient:IrohaClientBuilder
private irohaRequestParam:IrohaRequestParam
constructor(){
this.irohaRequestParam = new IrohaRequestParam()
}
public async exec (shopCode:string,nptransactionId:string):Promise<IrohaInterface> {
this.irohaClient = new IrohaClientBuilder()
const client = await this.irohaClient.buildIrohaClient()
const result = await client.searchTransactionAsync(this.irohaRequestParam.get(shopCode,nptransactionId))
return result[0].return
}
}
expect(received).toEqual(expected) // deep equality
- Expected - 37
+ Received + 6
Object {
"apiCommonResponseHeader": Object {
"attributes": Object {
"xsi:type": "ax22:ApiCommonResponseHeader",
},
- "requestId": "12345",
- "resultStatus": 0,
+ "errorCodeList": Array [
+ "E0000007",
+ ],
+ "requestId": "PRC220909141357mwdix",
+ "resultStatus": 90,
"serviceType": "01",
- "shopCode": "akt0000001",
+ "shopCode": "testArg1"}
}
20 | const mockfunc = jest.spyOn(iroha,"exec")
21 | mockfunc.mockReturnValue(Promise.resolve(irohaResponse))
> 22 | expect(await new IrohaTransactionExec().exec("testArg1","testArg2")).toEqual(irohaResponse)
| ^
23 | },10000)
at Object.<anonymous> (test/functions/transactions/handler.spec.ts:22:82)
----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files | 0 | 0 | 0 | 0 |
----------|---------|----------|---------|---------|-------------------
Test Suites: 1 failed, 1 total
Tests: 1 failed, 1 total
Snapshots: 0 total
Time: 3.754 s, estimated 4 s
I guess the issue is that in your expectation you are creating a new instance, and therefor it's not mocked anymore.
Following the docs, I would possible do the following:
import IrohaTransactionExec from './path-to-module';
const mockExec = jest.fn();
jest.mock('./path-to-module', () => {
return jest.fn().mockImplementation(() => {
return { exec: mockExec };
});
});
// OR
jest.mock('./path-to-module', () => ({
exec: mockExec
}));
// describe...
beforeEach(() => {
mockExec.mockResolvedValue(registered);
});
it("mocking test", async () => {
const res = await new IrohaTransactionExec().exec("testArg1","testArg2");
expect(res).toEqual(irohaResponse)
)}

How to reset Jasmine Spy object?

Not able to find docs for resetting the Jasmine Spy object.
If there is better way of using spy objects, please suggest.
// spec.js
import { mockService } from "./mockService"; // mockService = jasmine.createSpyObj(...)
describe('test', () => {
beforeEach(function () {
// NOTE: Following don't work
// mockService.reset();
// mockService.calls.reset();
// mockService.method.calls.reset();
});
it('a', () => {
mockService.fn();
expect(mockService.fn).toHaveBeenCalledTimes(1);
});
it('b', () => {
mockService.fn();
expect(mockService.fn).toHaveBeenCalledTimes(1);
});
});
It should work as expected.
E.g.
const service = {
fn() {},
};
const mockService = jasmine.createSpyObj(service, 'fn');
describe('test', () => {
beforeEach(function () {
mockService.fn.calls.reset();
});
it('a', () => {
mockService.fn();
expect(mockService.fn).toHaveBeenCalledTimes(1);
});
it('b', () => {
mockService.fn();
expect(mockService.fn).toHaveBeenCalledTimes(1);
});
});
unit test results:
Randomized with seed 28798
Started
..
2 specs, 0 failures
Finished in 0.02 seconds
Randomized with seed 28798 (jasmine --random=true --seed=28798)
---------------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
---------------|---------|----------|---------|---------|-------------------
All files | 100 | 100 | 80 | 100 |
index.spec.js | 100 | 100 | 80 | 100 |
---------------|---------|----------|---------|---------|-------------------
Incorrect way: spyObj.calls.reset()
Correct way: spyObj.spyMethod.calls.reset()
NOTE: calls.reset() is done for spy methods and not for spy object.
Jasmine reset() docs

Mocking nested functions in jestjs

I have a very complex object i am using to mock out a DataTable() object for the purposes of testing.
const obj = {
DataTable: () => {
return {
columns: () => {
return {
data: () => {
return {
eq: () => {
return {
indexOf: jest.fn(),
};
},
};
},
visible: () => {
return jest.fn();
},
};
},
};
},
};
Inside my testing code I am trying to spy on some of these functions but it always returns undefined. Is there a way to mock out the return value of deeply nested functions?
jest.spyOn(obj.DataTable().columns().data().eq(), 'indexOf').mockReturnValue('test');
console.log(obj.DataTable().columns().data().eq().indexOf()); // returns undefined, should return 'test'
Here is the unit test solution:
index.ts:
import { obj } from './obj';
export function main() {
return obj.DataTable().columns().data().eq().indexOf();
}
obj.ts:
export const obj = {
DataTable: () => {
return {
columns: () => {
return {
data: () => {
return {
eq: () => {
return {
indexOf: () => 'real data',
};
},
};
},
};
},
};
},
};
index.test.ts:
import { main } from './';
import { obj } from './obj';
describe('61396089', () => {
afterEach(() => {
jest.restoreAllMocks();
});
it('should pass', () => {
const mockDataTable = {
columns: jest.fn().mockReturnThis(),
data: jest.fn().mockReturnThis(),
eq: jest.fn().mockReturnThis(),
indexOf: jest.fn().mockReturnValueOnce('fake data'),
};
jest.spyOn(obj, 'DataTable').mockImplementationOnce(() => mockDataTable);
const actual = main();
expect(actual).toBe('fake data');
expect(mockDataTable.columns).toBeCalledTimes(1);
expect(mockDataTable.data).toBeCalledTimes(1);
expect(mockDataTable.eq).toBeCalledTimes(1);
expect(mockDataTable.indexOf).toBeCalledTimes(1);
});
});
unit test results with coverage report:
PASS stackoverflow/61396089/index.test.ts (20.978s)
61396089
✓ should pass (8ms)
----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files | 44.44 | 100 | 16.67 | 44.44 |
index.ts | 100 | 100 | 100 | 100 |
obj.ts | 16.67 | 100 | 0 | 16.67 | 3-10
----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 23.889s
source code: https://github.com/mrdulin/react-apollo-graphql-starter-kit/tree/master/stackoverflow/61396089

How to test jest mock module

// utils.js
var someModule = require('someModule');
someModule.setKey('API_KEY');
I want to test setKey function. So I wrote below unit test case.
jest.mock('someModule, () => {
return {
setKey: jest.fn()
}
})
describe('utils', () => {
afterEach(()=> {
jest.clearAllMocks()
})
it(`test case 1`, () => {})
it(`test case utils`, () => {
expect(someModule.setKey.mocks.calls).toHaveLength(1)
})
});
Last test case fails, but if I move the last test case as first then it works. Since there is no clearAllMocks function executed.
What should be a good way to test it?
It should work. Here is an example:
utils.js:
const someModule = require('someModule');
function main() {
someModule.setKey('API_KEY');
}
module.exports = main;
Since the someModule is not a real module, so I use {virtual: true} option.
utils.test.js:
const main = require('./utils');
const someModule = require('someModule');
jest.mock(
'someModule',
() => {
return { setKey: jest.fn() };
},
{ virtual: true },
);
describe('60192332', () => {
afterEach(() => {
jest.clearAllMocks();
});
it('should set key', () => {
main();
expect(someModule.setKey.mock.calls).toHaveLength(1);
});
});
Unit test results with 100% coverage:
PASS stackoverflow/60192332/utils.test.js (6.732s)
60192332
✓ should set key (5ms)
----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files | 100 | 100 | 100 | 100 |
utils.js | 100 | 100 | 100 | 100 |
----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 8.38s, estimated 13s

Partially mocking a module

I have the following file I would like to test
functions.js:
function funcOne() {
return funcTwo();
}
function funcTwo() {
return 'func two';
}
module.exports = {
funcOne,
funcTwo
};
I want to mock the funcTwo so that it returns me different string when called through my functions.funcOne
functions.test.js:
function mockFunctions() {
const original = require.requireActual('./functions');
return {
...original, // Pass down all the exported objects
funcTwo: jest.fn(() => {
return 'my test func';
})
};
}
jest.mock('./functions', () => mockFunctions());
const functions = require.requireMock('./functions');
it('renders without crashing', () => {
console.log(functions.funcOne());
});
It still prints me 'func two' instead of 'my test func'.
Is there a way to leave the module intact and just mock one particular method?
Here is a solution:
functions.js:
function funcOne() {
return exports.funcTwo();
}
function funcTwo() {
return 'func two';
}
exports.funcOne = funcOne;
exports.funcTwo = funcTwo;
Unit test:
functions.spec.js
const functions = require('./functions');
describe('functions test suites', () => {
it('funcOne', () => {
const funcTwoSpyOn = jest.spyOn(functions, 'funcTwo').mockReturnValueOnce('my test func');
const actualValue = functions.funcOne();
expect(actualValue).toBe('my test func');
expect(funcTwoSpyOn).toBeCalledTimes(1);
funcTwoSpyOn.mockRestore();
});
it('funcTwo', () => {
const actualValue = functions.funcTwo();
expect(actualValue).toBe('func two');
});
});
Unit test result with 100% coverage:
PASS src/stackoverflow/53889291/functions.spec.js
functions test suites
✓ funcOne (5ms)
✓ funcTwo
--------------|----------|----------|----------|----------|-------------------|
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
--------------|----------|----------|----------|----------|-------------------|
All files | 100 | 100 | 100 | 100 | |
functions.js | 100 | 100 | 100 | 100 | |
--------------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests: 2 passed, 2 total
Snapshots: 0 total
Time: 3.199s
Here is the completed demo: https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/53889291

Categories