如何在Jest中模拟React上下文

huangapple go评论65阅读模式
英文:

How to mock React Context in Jest

问题

I see that you're encountering an issue with your React component testing. It appears that you're trying to use the useArtifactsResumeContext hook within your ArtifactsResumeTitle component during testing, but you're getting an error because the context value is undefined.

To solve this issue, you can mock the context value when rendering your components for testing. Here's how you can do it:

import { render, fireEvent, screen } from '@testing-library/react';

// Mock the useArtifactsResumeContext hook
jest.mock('./path-to-useArtifactsResumeContext', () => ({
  useArtifactsResumeContext: jest.fn(),
}));

test('Block Link works properly', () => {
  // Provide a mock context value for testing
  useArtifactsResumeContext.mockReturnValue({ name: 'TestName' });

  render(
    <Provider store={AppStore()}>
      <MemoryRouter>
        <ArtifactsResumeContext.Provider value={BodyArtifacts[0]}>
          <ArtifactsBlock src='' name='Christian' />
          <AppRouter />
        </ArtifactsResumeContext.Provider>
      </MemoryRouter>
    </Provider>
  );

  fireEvent.click(screen.getAllByRole('link', { hidden: true })[0]);

  screen.debug();
});

Make sure to replace './path-to-useArtifactsResumeContext' with the actual path to your useArtifactsResumeContext module. This mock setup should provide the necessary context value for your testing, resolving the "Cannot destructure property 'name'" error.

英文:

I'm trying to test a React component that uses React Context.

Here is the provider component:

const ArtifactsResumeContext = createContext&lt;Artifact&gt;({} as Artifact);

export const useArtifactsResumeContext = () =&gt; useContext(ArtifactsResumeContext);

const ArtifactsResume = () =&gt; {
  useCallOnloadAnimation()
  const { name } = useParams();

  const artifact = ArtifactArray.flat().filter(
    (artifact) =&gt; artifact.name === name
  )[0];

  return (
    &lt;ColumnedFlex
      sx={{
        backgroundColor: &#39;#f4f4f4&#39;,
        gap: 10,
      }}
    &gt;
      &lt;PrevPageArrow /&gt;
      &lt;ArtifactsResumeContext.Provider value={artifact}&gt;
        &lt;ArtifactsResumeTitle /&gt;
        &lt;ArtifactsResumeContent /&gt;
      &lt;/ArtifactsResumeContext.Provider&gt;
    &lt;/ColumnedFlex&gt;
 );
};

export default ArtifactsResume;

Here is one of the consumer components:

const ArtifactsResumeTitle = () =&gt; {
  const { name } = useArtifactsResumeContext();
  return (
    &lt;IsLoading&gt;
      &lt;Typography
        color=&#39;primary&#39;
        variant=&#39;h1&#39;
        fontSize={50}
        mt={10}
      &gt;
        {name}
      &lt;/Typography&gt;
    &lt;/IsLoading&gt;
  );
};

export default ArtifactsResumeTitle;

The problem begins when I try to test the component like this:

test(&#39;Block Link works properly&#39;, () =&gt; {
  render(
    &lt;Provider store={AppStore()}&gt;
      &lt;MemoryRouter&gt;
        &lt;ArtifactsResumeContext.Provider value={BodyArtifacts[0]} &gt;
          &lt;ArtifactsBlock src=&#39;&#39; name=&#39;Christian&#39; /&gt;
          &lt;AppRouter /&gt;
        &lt;/ ArtifactsResumeContext.Provider&gt;
      &lt;/MemoryRouter&gt;
    &lt;/Provider&gt;
  );

  fireEvent.click(screen.getAllByRole(&#39;link&#39;, {
    hidden: true
  })[0])

  screen.debug()
});

Basically ArtifactsBlock component contains the link that redirects to the provider component shown above, and AppRouter is where all my routes are. Then, using fireEvent, I click this link and, for the time being, log what's inside. However I get this errors instead:

*TypeError: Cannot destructure property 'name' of '(0 , _ArtifactsResume.useArtifactsResumeContext)(...)' as it is undefined.

  4 |
  5 | const ArtifactsResumeTitle = () =&gt; {
&gt; 6 |       const { name } = useArtifactsResumeContext();
    |               ^
  7 |       return (
  8 |               &lt;IsLoading&gt;
  9 |                       &lt;Typography*

I tried mocking context and wrapping my ArtifactsBlock in the Provider but nothing seems to work. What am I missing?

答案1

得分: 1

Sure, here is the translated content:

需要将您的应用程序包装在上下文提供程序中:

<YourContextName.Provider value={YourValue}>
   //您的应用程序的其余部分
</YourContext.Provider>
英文:

you need to wrap your application with the Context Provider

    &lt;YourContextName.Provider value={YourValue}&gt;
       //The Rest Of Your App
    &lt;/YourContext.Provider&gt;

huangapple
  • 本文由 发表于 2023年5月21日 22:49:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/76300477.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定