如何使用 typescript、react 和 jest 进行手动模拟?

Emr*_*son 4 mocking typescript reactjs react-tsx ts-jest

我试图使用 jest 来模拟 React 组件使用的钩子的返回值,但我无法让它工作。考虑价格标签部分。它所做的只是渲染从挂钩返回的价格usePrice

usePrice.ts

export default function usePrice() {
  return 1337;
}
Run Code Online (Sandbox Code Playgroud)

PriceTag.tsx

import React from 'react';
import usePrice from './usePrice';

export default function PriceTag() {
  const price = usePrice();

  return <p>Price: {price}</p>
}
Run Code Online (Sandbox Code Playgroud)

在测试中,我断言显示了正确的价格。由于我想为此组件创建多个测试,因此setPrice使用帮助器为每个测试设置下一个返回值。

__mocks__/usePrice.ts

let price = 58008;

export function setPrice(newPrice) {
  price = newPrice;
}

export default function usePrice() {
  return price;
}
Run Code Online (Sandbox Code Playgroud)

PriceTag.test.tsx

import { render } from '@testing-library/react';
import React from 'react';
import PriceTag from './PriceTag';
import { setPrice } from './__mocks__/usePrice';

jest.mock('./usePrice');

describe('PriceTag', () => {
  it('renders the price', () => {
    setPrice(100);
    const { getByText } = render(<PriceTag />);

    const textEl = getByText('Price: 100');

    expect(textEl).toBeInTheDocument();
  });
});
Run Code Online (Sandbox Code Playgroud)

当我运行测试时,出现以下失败:

    TestingLibraryElementError: Unable to find an element with the text: Price: 100. This could be because the text is broken up by multiple elements. In this case, you can pro
vide a function for your text matcher to make your matcher more flexible.

    <body>
      <div>
        <p>
          Price:
          58008
        </p>
      </div>
    </body>

      11 |     const { getByText } = render(<PriceTag />);
      12 |
    > 13 |     const textEl = getByText('Price: 100');
         |                    ^
      14 |
      15 |     expect(textEl).toBeInTheDocument();
      16 |   });
Run Code Online (Sandbox Code Playgroud)

我可以看到从那时起就使用了模拟58008它是在 DOM 中渲染的。不过,我希望100能被退回。我相信这是由于 Jest 提升变量的方式造成的,但如果我能让它发挥作用,那将非常有用。

此代码直接受到他们模拟fs模块示例的启发:https ://jestjs.io/docs/manual-mocks#examples

Kev*_*erg 7

我相信您看到的问题是由于您正在导入模拟本身。

import { setPrice } from './__mocks__/usePrice';
Run Code Online (Sandbox Code Playgroud)

Jest 希望您导入实际的模块。尝试将其更改为

import { setPrice } from './usePrice';
Run Code Online (Sandbox Code Playgroud)