gpt4 book ai didi

javascript - 如何在自定义 Hook 中测试 useEffect?

转载 作者:行者123 更新时间:2023-12-05 02:45:56 27 4
gpt4 key购买 nike

所以我对使用 React 进行测试还很陌生。我有一个在组件内部调用的自定义 Hook 。我正在使用 react-hook-testing-library 中的 renderHook 方法。

我需要测试是否调用了自定义 Hook 内 useEffect 内的方法。我似乎无法弄清楚这一点。

在另一种情况下,我需要弄清楚 trackPdpGtm 是否未被调用。

注意:钩子(Hook)不返回任何数据。这主要用于发送分析信息。

当前方法:

使用PdpGtm.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]);
}

我需要测试是否调用了 trackPdpGtm。还需要检查它是否未在另一个测试用例中调用。

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

});

还尝试使用 trackGtmPdp.mock.calls.length.toBe(1)

usePdpGtm Hook 在 ProductDescriptionComponent 中调用,并接收一个对象作为其参数。

注意:自定义 Hook 在测试期间没有运行。我不确定,但是在测试运行时不会打印里面的 console.log 语句。

非常感谢任何帮助。

最佳答案

您忘记清除 trackPdpGtm 函数 mock 的 mock.callsmock.instances 属性。这就是您的第二个测试用例失败的原因。您可以使用 jest.clearAllMocks()afterEach 钩子(Hook)中清除它。

例如

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

单元测试结果:

 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

关于javascript - 如何在自定义 Hook 中测试 useEffect?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65703648/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com