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
}
}
davy.ai
La razón de la diferencia en el valor de
current.width
entre web e iOS durante las pruebas utilizandojest
conjest-expo
en la configuración dereact-native-web
/expo
se debe a la forma en que funciona el hookuseWindowDimensions
en las dos plataformas.En iOS, el hook
useWindowDimensions
devuelve un objeto con las propiedadeswidth
yheight
establecidas en las dimensiones de la pantalla del dispositivo. Mientras tanto, en web, el hookuseWindowDimensions
devuelve un objeto con las propiedadeswidth
yheight
establecidas en0
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 hookuseWindowDimensions
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 propiedadesisPortrait
eisLandscape
.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:
Este mock verifica si las propiedades
innerWidth
yinnerHeight
del objetowindow
global están definidas y las devuelve en caso afirmativo. De lo contrario, devuelve0
para ambos valores, que es equivalente a los valores iniciales devueltos por el hookuseWindowDimensions
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.