how to test scroll event handler in jest - javascript

I am calling $('.all-products-tab-buttons .row').scroll() method in my js file. But can't find out how to test this method using JEST.
Full code is below:
$('.all-products-tab-buttons .row').scroll(event => {
let $width = $('.all-products-tab-buttons .row').outerWidth();
let $scrollWidth = $('.all-products-tab-buttons .row')[0].scrollWidth;
let $scrollLeft = $('.all-products-tab-buttons .row').scrollLeft();
if ($scrollWidth - $width === $scrollLeft) {
$('.all-products-tab-buttons').addClass('remove');
} else {
$('.all-products-tab-buttons').removeClass('remove');
}
});
How may I test if and else conditions also?

Here is the unit test solution:
index.js:
import $ from 'jquery';
function main() {
$('.all-products-tab-buttons .row').scroll((event) => {
let $width = $('.all-products-tab-buttons .row').outerWidth();
let $scrollWidth = $('.all-products-tab-buttons .row')[0].scrollWidth;
let $scrollLeft = $('.all-products-tab-buttons .row').scrollLeft();
if ($scrollWidth - $width === $scrollLeft) {
$('.all-products-tab-buttons').addClass('remove');
} else {
$('.all-products-tab-buttons').removeClass('remove');
}
});
}
export default main;
index.test.js:
import main from './';
import $ from 'jquery';
jest.mock('jquery', () => jest.fn());
describe('60003884', () => {
it('should add class', () => {
const tabButtonRows = [{ scrollWidth: 200 }];
tabButtonRows.constructor.prototype.scroll = jest.fn().mockImplementationOnce((handler) => {
handler();
});
tabButtonRows.constructor.prototype.outerWidth = jest.fn().mockReturnValueOnce(100);
tabButtonRows.constructor.prototype.scrollLeft = jest.fn().mockReturnValueOnce(100);
const tabButtons = { addClass: jest.fn(), removeClass: jest.fn() };
$.mockImplementation((selector) => {
switch (selector) {
case '.all-products-tab-buttons .row':
return tabButtonRows;
case '.all-products-tab-buttons':
return tabButtons;
}
});
main();
expect(tabButtons.addClass).toBeCalledWith('remove');
});
it('should remove class', () => {
const tabButtonRows = [{ scrollWidth: 200 }];
tabButtonRows.constructor.prototype.scroll = jest.fn().mockImplementationOnce((handler) => {
handler();
});
tabButtonRows.constructor.prototype.outerWidth = jest.fn().mockReturnValueOnce(100);
tabButtonRows.constructor.prototype.scrollLeft = jest.fn().mockReturnValueOnce(50);
const tabButtons = { addClass: jest.fn(), removeClass: jest.fn() };
$.mockImplementation((selector) => {
switch (selector) {
case '.all-products-tab-buttons .row':
return tabButtonRows;
case '.all-products-tab-buttons':
return tabButtons;
}
});
main();
expect(tabButtons.removeClass).toBeCalledWith('remove');
});
});
Unit test results with 100% coverage:
PASS src/stackoverflow/60003884/index.test.js (14.309s)
60003884
✓ should add class (7ms)
✓ should remove class (1ms)
----------|----------|----------|----------|----------|-------------------|
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
----------|----------|----------|----------|----------|-------------------|
All files | 100 | 100 | 100 | 100 | |
index.js | 100 | 100 | 100 | 100 | |
----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests: 2 passed, 2 total
Snapshots: 0 total
Time: 16.079s
Source code: https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/60003884

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)
)}

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

How to test Json.parse using Jest

I am new to Jest and i am trying test async await. And I am trying to cover Json.Parse and it is throwing an exception like below mentioned.
Error Message
SyntaxError: Unexpected token o in JSON at position 1
at JSON.parse (<anonymous>)
Code
public async callDataSourceCommand(dialogData: any, RecipeId: string) {
const gridItems = await this.dataSourceService.myPromiseMethod(id, collection);
this.updateGrid(JSON.parse(gridItems));
}
private updateGrid(gridItems: any) {}
Mock Data
public get dataSourceServiceMock(): any = {
return {
myPromiseMethod: function () {
return Promise.resolve({
selectedOrder: {
earlierStartTime: '2/5/2020',
__id: 'orderId123'
},
Collection: [{
__id: 'b1order 1',
resName: 'New recipe_V1.0',
plannedQuantity: '3',
resId: 'ns=6;s=4/ProjectData/1',
actualQuantity: '1',
description: 'batchDesc',
}]
});
}
}
}
Test Suite
it('1. Should execute ', async() => {
const myDialogApp: DialogApp = TestBed.get(DialogApp);
myDialogApp.selectedOrder = selectedOrder;
myDialogApp.RecipeId = Recipe.__id;
jest.spyOn(dataSourceServiceMock, 'myPromiseMethod');
await myDialogApp.callDataSourceCommand(dialogData, RecipeId);
expect(dataSourceServiceMock.myPromiseMethod).toHaveBeenCalled();
});
Well, you can simply stub the response and pass it as below
public get dataSourceServiceMock(): any = {
return {
myPromiseMethod: function () {
return Promise.resolve(JSON.stringify({
selectedOrder: {
earlierStartTime: '2/5/2020',
__id: 'orderId123'
},
Collection: [{
__id: 'b1order 1',
resName: 'New recipe_V1.0',
plannedQuantity: '3',
resId: 'ns=6;s=4/ProjectData/1',
actualQuantity: '1',
description: 'batchDesc',
}]
}));
}
}
}
Hope this helps!
Here is the unit test solution:
index.ts:
class Service {
private dataSourceService;
constructor(dataSourceService) {
this.dataSourceService = dataSourceService;
}
public async callDataSourceCommand(dialogData: any, RecipeId: string) {
const id = '1';
const collection = [];
const gridItems = await this.dataSourceService.myPromiseMethod(id, collection);
this.updateGrid(JSON.parse(gridItems));
}
private updateGrid(gridItems: any) {}
}
export { Service };
datasourceService.ts:
class DataSourceService {
public myPromiseMethod(id, collection) {
return JSON.stringify({});
}
}
export { DataSourceService };
index.test.ts:
import { Service } from './';
describe('60446313', () => {
it('should pass', async () => {
const gridItemsMock = JSON.stringify({
selectedOrder: {
earlierStartTime: '2/5/2020',
__id: 'orderId123',
},
Collection: [
{
__id: 'b1order 1',
resName: 'New recipe_V1.0',
plannedQuantity: '3',
resId: 'ns=6;s=4/ProjectData/1',
actualQuantity: '1',
description: 'batchDesc',
},
],
});
const dataSourceServiceMock = {
myPromiseMethod: jest.fn().mockResolvedValueOnce(gridItemsMock),
};
const parseSpy = jest.spyOn(JSON, 'parse');
const service = new Service(dataSourceServiceMock);
await service.callDataSourceCommand('dialogData', '1');
expect(dataSourceServiceMock.myPromiseMethod).toBeCalledWith('1', []);
expect(parseSpy).toBeCalledWith(gridItemsMock);
});
});
Unit test results with coverage report:
PASS stackoverflow/60446313/index.test.ts
60446313
✓ should pass (9ms)
----------|---------|----------|---------|---------|-------------------
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: 4.509s, estimated 6s

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