Hace poco quise probar que algún método personalizado se llama condicionalmente en el método componentDidMount de un componente React.
componentDidMount() { if (this.props.initOpen) { this.methodName(); } } Estoy usando Jest como mi marco de prueba, que incluye jest.fn() para simulacros/espías. He leído que sería bastante trivial probarlo con Sinon, haciendo algo como lo siguiente:
sinon.spy(Component.prototype, "methodName"); const wrapper = mount(<Component {...props} />); expect(wrapper.instance().methodName).toHaveBeenCalled();Estoy tratando de recrear esto con Jest así:
Component.prototype.methodName = jest.fn(); const wrapper = mount(<Component {...props} />); expect(wrapper.instance().methodName).toHaveBeenCalled();Este código falla y arroja el siguiente error:
jest.fn() value must be a mock function or spy. Received: function: [Function bound mockConstructor]¿Es posible probar esta funcionalidad con Jest? Y si es así, ¿cómo?
La clave es usar el método spyOn en el prototype del objeto. Debería ser así:
const spy = jest.spyOn(Component.prototype, 'methodName'); const wrapper = mount(<Component {...props} />); wrapper.instance().methodName(); expect(spy).toHaveBeenCalled();Como se encuentra aquí, por ejemplo: prueba si la función se llama reaccionar y enzima
Tenga en cuenta que también es una buena práctica borrar la función espiada después de cada ejecución de prueba
let spy afterEach(() => { spy.mockClear() })https://facebook.github.io/jest/docs/en/jest-object.html#jestclearallmocks
Sé que es un poco tarde, pero encontré esto y sugeriría que para probar el componentDidMount inicie la llamada a su método anidado para que su prueba se vea así:
Módulo
componentDidMount() { if (this.props.initOpen) { this.methodName(); } }Prueba - Bueno
it('should call methodName during componentDidMount', () => { const methodNameFake = jest.spyOn(MyComponent.prototype, 'methodName'); const wrapper = mount(<MyComponent {...props} />); expect(methodNameFake).toHaveBeenCalledTimes(1); }); Si llama a componentDidMount entonces la afirmación de que methodName se llamó a través de componentDidMount es más válida.
Prueba - Mala
it('should call methodName during componentDidMount', () => { const spy = jest.spyOn(Component.prototype, 'methodName'); const wrapper = mount(<Component {...props} />); wrapper.instance().methodName(); expect(spy).toHaveBeenCalled(); }Al escribir la prueba de esta manera, llama al método y luego afirma que fue llamado. Que por supuesto te habrá dado nada más llamarlo.
Si está tratando de probar los métodos public que se llaman en el componentDidMount (si está usando TypeScript), deberá llamar explícitamente a la llamada al método del componentDidMount de la instance , ya que los métodos públicos no se definen hasta después de que el componente es instanciado
Para probar algo como esto:
Código
public componentDidMount() { if (this.props.initOpen) { this.methodName(); } } public methodName = () => { // some code here }Prueba
it('should call methodName during componentDidMount', () => { const wrapper = mount(<MyComponent {...props} />); const instance = wrapper.instance(); jest.spyOn(instance, 'methodName') expect(instance.methodName).toHaveBeenCalled(); });