es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

El mock de jest de react-native-web funciona para iOS pero no para web.

En una configuración de react-native-web / expo, durante las pruebas utilizando jest con jest-expo, la configuración de web e ios, la siguiente simulación siempre parece ser 0 en web pero 300 en ios.

La prueba:

import { renderHook } from '@testing-library/react-hooks'
import { useOrientation } from './index'

function mockDimensions({ width, height }) {
  jest.resetModules()
  jest.doMock('react-native/Libraries/Utilities/useWindowDimensions', () => {
    return {
      default: jest.fn(() => ({ width, height }))
    }
  })
}

describe('Test resultado de orientación basado en las dimensiones de pantalla', () => {
  afterEach(cleanup)
  test('isPortrait debería ser verdadero', async () => {
    mockDimensions({ width: 300, height: 600 })
    const { result: { current } } = renderHook(useOrientation)
    console.log(current.width). // <-- 0 en web, 300 en ios
    await expect(current.isPortrait).toBe(true)
    await expect(current.isLandscape).toBe(false)
  })
})

El componente:

import { useWindowDimensions } from 'react-native'

export function useOrientation() {
  const { width, height } = useWindowDimensions()
  return {
    width,
    height,
    isPortrait: height > width,
    isLandscape: width > height
  }
}
Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    La razón de la diferencia en el valor de current.width entre web e iOS durante las pruebas utilizando jest con jest-expo en la configuración de react-native-web/expo se debe a la forma en que funciona el hook useWindowDimensions en las dos plataformas.

    En iOS, el hook useWindowDimensions devuelve un objeto con las propiedades width y height establecidas en las dimensiones de la pantalla del dispositivo. Mientras tanto, en web, el hook useWindowDimensions devuelve un objeto con las propiedades width y height establecidas en 0 inicialmente. Estos valores se actualizan una vez que el componente es montado y renderizado en el navegador.

    El mock creado en la prueba utilizando jest.doMock reemplaza la implementación del hook useWindowDimensions con una personalizada que devuelve los valores dados como dimensiones de la pantalla. Dado que el componente no está montado durante la prueba, los valores devueltos por el mock son los que se utilizan para calcular las propiedades isPortrait e isLandscape.

    Por lo tanto, para solucionar el problema, el mock debería ser actualizado con los valores apropiados para web e iOS, respectivamente. Una solución posible es crear un mock condicional que devuelva valores diferentes según la plataforma:

    jest.doMock('react-native/Libraries/Utilities/useWindowDimensions', () => ({
      default: () => ({
        width: global.window.innerWidth || 0,
        height: global.window.innerHeight || 0
      })
    }), { virtual: true })
    

    Este mock verifica si las propiedades innerWidth y innerHeight del objeto window global están definidas y las devuelve en caso afirmativo. De lo contrario, devuelve 0 para ambos valores, que es equivalente a los valores iniciales devueltos por el hook useWindowDimensions en web.

    Ten en cuenta que la opción { virtual: true } se agrega para asegurar que el mock se aplique al ámbito global del entorno de prueba, en lugar de estar aislado en el módulo que se está probando.

Comments are closed.