Monday, May 20, 2024
 Popular · Latest · Hot · Upcoming
101
rated 0 times [  104] [ 3]  / answers: 1 / hits: 7774  / 3 Years ago, wed, january 13, 2021, 12:00:00

So I'm pretty new to testing with react. I have a custom hook that I am calling inside a component. I am using the renderHook methods from react-hook-testing-library.


I need to test if the methods inside useEffect inside the custom hook are called. I cant seem to figure this out.


In another case, I need to figure out if trackPdpGtm is not called.


Note: The hook does not return any data. This is mainly for sending analytics information.


Current Approach:


usePdpGtm.js


import { useEffect } from 'react';
import { trackPdpGtm } from 'utils/gtm/pdpGtmUtils';
import _ from 'utils/lodashImports';

export default function useGtmPdp(data = {}) {
console.log('are you getting called?');
const { relatedProducts, results, priceInfo, breadcrumbs } = data;
const relatedProductsLoaded = _.get(relatedProducts, 'relatedProductsLoaded');
useEffect(() => {
if (relatedProductsLoaded) {
trackPdpGtm(data);
}
}, [relatedProductsLoaded, results, priceInfo, breadcrumbs]);
}


I need to test if trackPdpGtm are called. Also need to check that its not called in another test case.


gtm.test.js


import { renderHook, cleanup, act } from 'react-hooks-testing-library';
import usePdpGtm from 'utils/hooks/gtmHooks/usePdpGtm';
import useListPageGtm from 'utils/hooks/gtmHooks/useListPageGtm';
import { trackPdpGtm } from 'utils/gtm/pdpGtmUtils';
import { trackListPageGtm } from 'utils/gtm/plpGtmUtils';
import { mount, shallow } from 'enzyme';
import { ProductDescriptionComponent } from 'components/business/ProductDescription/ProductDescriptionComponent';

jest.mock('utils/hooks/gtmHooks/usePdpGtm');
jest.mock('utils/hooks/gtmHooks/useListPageGtm');
jest.mock('utils/gtm/pdpGtmUtils');
jest.mock('utils/gtm/plpGtmUtils');

trackPdpGtm.mockImplementation = jest.fn();
// ALSO TRIED trackPdpGtm.mockImplementation(() => jest.fn());
trackListPageGtm.mockImplementation(() => console.log('adadada'));

describe('analytics helper', () => {
afterEach(cleanup);

it('should fire usePdpGtm Hook', async (done) => {
const pdpData = {
relatedProducts: {
collectionProducts: [],
relatedProductsLoaded: true
},
productInfo: {
variants: [{}],
breadcrumbs: [{}],
serviceWarrantyDetails: {
services: [],
warranties: [{}]
}
},
priceInfo: [{}],
breadcrumbs: [{}]
};
const { result } = renderHook(() => usePdpGtm(pdpData));
//THIS IS FAILING
expect(trackPdpGtm).toHaveBeenCalledTimes(1);
expect(result.current).toBeUndefined();
});

it('should fire usePdpGtm Hook without data', () => {
const { result } = renderHook(() => usePdpGtm(undefined));

// NEED TO TEST IF trackPdpGtm is NOT called. (also failing)

expect(trackPdpGtm).toNotBeCalled();
expect(result.current).toBeUndefined();
});

});


Also tried using trackGtmPdp.mock.calls.length.toBe(1).


The usePdpGtm hook is called inside ProductDescriptionComponent and receives an object as its argument.


Note: The custom hook is not running during the test. I am not sure but the console.log statements inside are not printed while the test is running.


Any help is highly appreciated.


More From » reactjs

 Answers
3

You forget to clear the mock.calls and mock.instances properties of trackPdpGtm function mock. That's why your second test case fails. You can use jest.clearAllMocks() to clear it in afterEach hook.


E.g.


usePdpGtm.ts:


// @ts-nocheck
import { useEffect } from 'react';
import { trackPdpGtm } from './pdpGtmUtils';
import _ from 'lodash';

export default function useGtmPdp(data = {}) {
console.log('are you getting called?');
const { relatedProducts, results, priceInfo, breadcrumbs } = data;
const relatedProductsLoaded = _.get(relatedProducts, 'relatedProductsLoaded');
useEffect(() => {
if (relatedProductsLoaded) {
trackPdpGtm(data);
}
}, [relatedProductsLoaded, results, priceInfo, breadcrumbs]);
}

pdpGtmUtils.ts:


export function trackPdpGtm(data) {
console.log('real track pdp gtm implementation');
}

usePdpGtm.test.ts:


import { renderHook, cleanup } from '@testing-library/react-hooks';
import usePdpGtm from './usePdpGtm';
import { trackPdpGtm } from './pdpGtmUtils';

jest.mock('./pdpGtmUtils');

describe('analytics helper', () => {
afterEach(() => {
jest.clearAllMocks();
cleanup();
});

it('should fire usePdpGtm Hook', () => {
const pdpData = {
relatedProducts: {
collectionProducts: [],
relatedProductsLoaded: true,
},
productInfo: {
variants: [{}],
breadcrumbs: [{}],
serviceWarrantyDetails: {
services: [],
warranties: [{}],
},
},
priceInfo: [{}],
breadcrumbs: [{}],
};
const { result } = renderHook(() => usePdpGtm(pdpData));
expect(trackPdpGtm).toHaveBeenCalledTimes(1);
expect(result.current).toBeUndefined();
});

it('should fire usePdpGtm Hook without data', () => {
const { result } = renderHook(() => usePdpGtm(undefined));
expect(trackPdpGtm).not.toBeCalled();
expect(result.current).toBeUndefined();
});
});

unit test result:


 PASS  examples/65703648/usePdpGtm.test.ts
analytics helper
✓ should fire usePdpGtm Hook (28 ms)
✓ should fire usePdpGtm Hook without data (4 ms)

console.log
are you getting called?

at Object.useGtmPdp [as default] (examples/65703648/usePdpGtm.ts:7:11)

console.log
are you getting called?

at Object.useGtmPdp [as default] (examples/65703648/usePdpGtm.ts:7:11)

----------------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------------|---------|----------|---------|---------|-------------------
All files | 91.67 | 100 | 66.67 | 91.67 |
pdpGtmUtils.ts | 50 | 100 | 0 | 50 | 2
usePdpGtm.ts | 100 | 100 | 100 | 100 |
----------------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 2 passed, 2 total
Snapshots: 0 total
Time: 5.167 s

[#1968] Friday, January 8, 2021, 3 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
calicinthias

Total Points: 447
Total Questions: 101
Total Answers: 118

Location: Botswana
Member since Sat, Dec 31, 2022
1 Year ago
calicinthias questions
Sun, Jan 2, 22, 00:00, 2 Years ago
Mon, Aug 10, 20, 00:00, 4 Years ago
Fri, May 15, 20, 00:00, 4 Years ago
;