Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

351
Views
¿Cómo probar un componente de reacción que depende del gancho useContext?

Tengo un componente que usa useContext y luego su salida depende del valor en el contexto. Un ejemplo sencillo:

 import React, { useContext } from 'react'; const MyComponent = () => { const name = useContext(NameContext); return <div>{name}</div>; };

Al probar este componente con el renderizador superficial de instantáneas de reacción y broma. ¿Cómo puedo cambiar el valor de NameContext ?

over 4 years ago · Santiago Trujillo
3 answers
Answer question

0

En general, el uso de ganchos no debería cambiar mucho la estrategia de prueba. El mayor problema aquí en realidad no es el gancho, sino el uso del contexto, lo que complica un poco las cosas.

Hay varias formas de hacer que esto funcione, pero el único enfoque que he encontrado que funciona con 'react-test-renderer/shallow' es inyectar un gancho simulado:

 import ShallowRenderer from 'react-test-renderer/shallow'; let realUseContext; let useContextMock; // Setup mock beforeEach(() => { realUseContext = React.useContext; useContextMock = React.useContext = jest.fn(); }); // Cleanup mock afterEach(() => { React.useContext = realUseContext; }); test("mock hook", () => { useContextMock.mockReturnValue("Test Value"); const element = new ShallowRenderer().render( <MyComponent /> ); expect(element.props.children).toBe('Test Value'); });

Sin embargo, esto es un poco sucio y específico de la implementación, por lo que si puede comprometer el uso del renderizador superficial, hay algunas otras opciones disponibles:

renderizado no superficial

Si no está renderizando superficialmente, puede envolver el componente en un proveedor de contexto para inyectar el valor que desea:

 import TestRenderer from 'react-test-renderer'; test("non-shallow render", () => { const element = new TestRenderer.create( <NameContext.Provider value="Provided Value"> <MyComponent /> </NameContext.Provider> ); expect(element.root.findByType("div").children).toEqual(['Provided Value']); });

(Descargo de responsabilidad: esto debería funcionar, pero cuando lo pruebo, aparece un error que creo que es un problema en mi configuración)

Render superficial con Enzyme y Dive

Como comentó @skyboyer, el renderizador superficial de enzima es compatible con .dive , lo que le permite renderizar profundamente una parte de un componente renderizado superficial:

 import { shallow } from "./enzyme"; test("enzyme dive", () => { const TestComponent = () => ( <NameContext.Provider value="Provided Value"> <MyComponent /> </NameContext.Provider> ); const element = shallow(<TestComponent />); expect(element.find(MyComponent).dive().text()).toBe("Provided Value"); });

Usar ReactDOM

Finalmente, las Preguntas frecuentes sobre ganchos tienen un ejemplo de prueba de ganchos con ReactDOM , que también funciona. Naturalmente, usar ReactDOM significa que este también es un renderizado profundo, no superficial.

 let container; beforeEach(() => { container = document.createElement('div'); document.body.appendChild(container); }); afterEach(() => { document.body.removeChild(container); container = null; }); test("with ReactDOM", () => { act(() => { ReactDOM.render(( <NameContext.Provider value="Provided Value"> <MyComponent /> </NameContext.Provider> ), container); }); expect(container.textContent).toBe("Provided Value"); });
over 4 years ago · Santiago Trujillo Report

0

Traté de usar Enzyme + .dive , pero al bucear, no reconoce los accesorios de contexto, obtiene los predeterminados. En realidad, es un problema conocido por el equipo de Enzyme. Mientras tanto, se me ocurrió una solución más simple que consiste en crear un enlace personalizado solo para devolver useContext con su contexto y simular el regreso de este enlace personalizado en la prueba:

AppContext.js: crea el contexto.

 import React, { useContext } from 'react'; export const useAppContext = () => useContext(AppContext); const defaultValues = { color: 'green' }; const AppContext = React.createContext(defaultValues); export default AppContext;

App.js — Proporcionar el contexto

 import React from 'react'; import AppContext from './AppContext'; import Hello from './Hello'; export default function App() { return ( <AppContext.Provider value={{ color: 'red' }}> <Hello /> </AppContext.Provider> ); }

Hello.js - Consumir el contexto

 import React from 'react'; import { useAppContext } from './AppContext'; const Hello = props => { const { color } = useAppContext(); return <h1 style={{ color: color }}>Hello {color}!</h1>; }; export default Hello;

Hello.test.js - Prueba de useContext con Enzyme superficial

 import React from 'react'; import { shallow } from 'enzyme'; import * as AppContext from './AppContext'; import Hello from './Hello'; describe('<Hello />', () => { test('it should mock the context', () => { const contextValues = { color: 'orange' }; jest .spyOn(AppContext, 'useAppContext') .mockImplementation(() => contextValues); const wrapper = shallow(<Hello />); const h1 = wrapper.find('h1'); expect(h1.text()).toBe('Hello orange!'); }); });

Consulte el artículo completo de Medium en https://medium.com/7shifts-engineering-blog/testing-usecontext-react-hook-with-enzyme-shallow-da062140fc83

over 4 years ago · Santiago Trujillo Report

0

O si está probando su componente de forma aislada sin montar los componentes principales, simplemente puede burlarse de useContext:

 jest.mock('react', () => { const ActualReact = jest.requireActual('react') return { ...ActualReact, useContext: () => ({ }), // what you want to return when useContext get fired goes here } })
over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!