javascript Vitest:在React中的消费者组件中模拟提供者的自定义useContext

kxeu7u2r  于 2023-09-29  发布在  Java
关注(0)|答案(1)|浏览(77)

前提

我有以下组件:

// providers/SomeContextProvider.tsx

import { createContext, ReactNode, useContext } from 'react';

const SomeContext = createContext('');

export type Props = {
  children: ReactNode;
};
export default function SomeContextProvider(props: Props) {
  const [someCalculatedValue, setSomeCalculatedValue] = useState();

  useEffect(() => {
    //calculate and set the someCalculatedValue
  }, [])

  return (
    <SomeContext.Provider value={someCalculatedValue}>
      {props.children}
    </SomeContext.Provider>
  );
}

export function useSomeContext() {
  return useContext(SomeContext);
}
// SomeConsumer.tsx

import { useSomeContext } from 'providers/SomeContextProvider'

return function SomeConsumer() {
  const contextValue = useSomeContext();

  return (/***/);
}

我想以一种可以控制从useSomeContext()得到的“计算值”的方式来测试SomeConsumer
为了做到这一点,我通过创建一个providers/__mocks__/SomeContextProvider.tsx来模拟SomeContextProvider.tsx文件(根据Vitest文档)

//providers/__mocks__/SomeContextProvider.tsx

import { createContext, ReactNode, useContext } from 'react';

const SomeContext = createContext('');

export type Props = {
  children: ReactNode;
  testValue: string; // Notice the mock provider accepts the value that it will pass down, as a prop
};
export default function SomeContextProvider(props: Props) {
  return (
    <SomeContext.Provider value={props.testValue}>
      {props.children}
    </SomeContext.Provider>
  );
}

export function useSomeContext() {
  return useContext(SomeContext);
}

然后在测试文件中模拟模块:

// SomeConsumer.test.tsx

import SomeConsumer from 'SomeConsumer.tsx';
import SomeContextProvider from 'providers/SomeContextProvider'
import { customRender } from 'test/utils';

vi.mock('providers/SomeContextProvider');

describe('SomeConsumer', function () {
  it('should match snapshot', () => {
    const { asFragment } = customRender(
      <SomeContextProvider testValue={'someValue}>
        <SomeConsumer>{/***/}</SomeConsumer>
      </SomeContextProvider>
    );

    expect(asFragment()).toMatchSnapshot();
  });
});

问题

问题是,虽然模拟的SomeContextProvider确实被调用了,但可以通过设置断点来确认这一点,SomeConsumer仍然调用从原始providers/SomeContextProvider.tsx导出的useSomeContext,而不是从providers/__mocks__/SomeContextProvider.tsx导出的useSomeContext,因此这并没有按预期工作。

问题

我怎样才能使它在测试SomeConsumer时使用从模拟SomeContextProvider.tsx文件导出的模拟useSomeContext

bpsygsoo

bpsygsoo1#

好吧,没关系,这似乎工作得很好,毕竟。原来我忘记了一个doMock而不是mock,当我测试这个的时候。一切都好

相关问题