Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/473.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何在自定义挂钩内测试useEffect?_Javascript_Reactjs_Jestjs_React Testing Library_React Hooks Testing Library - Fatal编程技术网

Javascript 如何在自定义挂钩内测试useEffect?

Javascript 如何在自定义挂钩内测试useEffect?,javascript,reactjs,jestjs,react-testing-library,react-hooks-testing-library,Javascript,Reactjs,Jestjs,React Testing Library,React Hooks Testing Library,所以我对react的测试还很陌生。我在一个组件中调用了一个自定义钩子。我正在使用react hook测试库中的renderHook方法 我需要测试定制钩子中的useffect方法是否被调用。我似乎无法理解这一点 在另一种情况下,我需要确定是否未调用trackPdpGtm 注意:钩子不会返回任何数据。这主要用于发送分析信息 当前方法: usepdppgtm.js import { useEffect } from 'react'; import { trackPdpGtm } from 'util

所以我对react的测试还很陌生。我在一个组件中调用了一个自定义钩子。我正在使用
react hook测试库中的
renderHook
方法

我需要测试定制钩子中的
useffect
方法是否被调用。我似乎无法理解这一点

在另一种情况下,我需要确定是否未调用
trackPdpGtm

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

当前方法:

usepdppgtm.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]);
}

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

});

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

gtm.test.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]);
}

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
钩子在
ProductDescriptionComponent
内部调用,并接收一个对象作为其参数

注意:测试期间,自定义挂钩未运行。我不确定,但测试运行时,不会打印其中的console.log语句


非常感谢您的帮助。

您忘记清除
mock.calls
mock.instances
函数mock的属性。这就是第二个测试用例失败的原因。您可以使用在每次挂钩后的
中清除它

例如

usepdppgtm.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]);
}
export function trackPdpGtm(data) {
  console.log('real track pdp gtm implementation');
}
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();
  });
});
pdpGtmUtils.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]);
}
export function trackPdpGtm(data) {
  console.log('real track pdp gtm implementation');
}
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();
  });
});
usepdppgtm.test.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]);
}
export function trackPdpGtm(data) {
  console.log('real track pdp gtm implementation');
}
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

您忘记清除
trackPdpGtm
函数mock的
mock.calls
mock.instances
属性。这就是第二个测试用例失败的原因。您可以使用在每次挂钩后的
中清除它

例如

usepdppgtm.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]);
}
export function trackPdpGtm(data) {
  console.log('real track pdp gtm implementation');
}
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();
  });
});
pdpGtmUtils.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]);
}
export function trackPdpGtm(data) {
  console.log('real track pdp gtm implementation');
}
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();
  });
});
usepdppgtm.test.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]);
}
export function trackPdpGtm(data) {
  console.log('real track pdp gtm implementation');
}
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

另请参见“谢谢”,但这不包括我正在尝试做的事情。另请参见“谢谢”,但这不包括我正在尝试做的事情。谢谢您的回答。但不幸的是,我现在面临一个奇怪的问题。这两种情况都失败了,但现在却截然相反。对于第一个测试用例,我得到:
预期呼叫数:1,接收到的呼叫数:0
,对于第二个测试用例:
预期呼叫数:0,接收到的呼叫数:1
,我不理解原因。我是否缺少@slideshowp2Update:我在第一个测试用例中执行第一个expect语句之前添加了一个延迟。基本上是通过setTimeout解决的承诺。所有测试用例都按预期开始工作。但是clearMocks应该解决这个问题。我似乎无法理解这个概念。我想你需要学习基础知识。谢谢你的回答。但不幸的是,我现在面临一个奇怪的问题。这两种情况都失败了,但现在却截然相反。对于第一个测试用例,我得到:
预期呼叫数:1,接收到的呼叫数:0
,对于第二个测试用例:
预期呼叫数:0,接收到的呼叫数:1
,我不理解原因。我是否缺少@slideshowp2Update:我在第一个测试用例中执行第一个expect语句之前添加了一个延迟。基本上是通过setTimeout解决的承诺。所有测试用例都按预期开始工作。但是clearMocks应该解决这个问题。我似乎无法理解这个概念。我想你需要学习基础知识。