Tengo MyComponent.tsx que usa el módulo constants.ts para hacer algo basado en la constante IS_IOS:

import React from 'react';
import { Text, View } from 'react-native';

import { platform } from '../../constants';

const { IS_IOS } = platform;
interface Props {}

export const MyComponent = (props: Props) => {
  return (
    <View>
      <Text>Alpha Beta { String(IS_IOS) }</Text>
    </View>
  );
};

Estoy tratando de simular constants.ts de manera diferente en cada prueba. Probé todos los métodos de aquí y aquí , pero aún no hay resultados. El módulo no se burla en absoluto. Aquí están mi archivo de prueba y el archivo de componentes:

MyComponent.test.tsx:

// @ts-nocheck
import React from 'react';
import { cleanup, render } from '@testing-library/react-native';
import { MyComponent } from '../../../src/MyComponent';

describe('MyComponent', () => {
  afterEach(() => {
    jest.resetModules();
    jest.clearAllMocks();
    cleanup();
  });

  it('one', () => {
    jest.mock('../../../src/constants', () => ({
      platform: { IS_IOS: false }
    }));

    const { debug } = render(<MyComponent/>);
    debug();
  });

  it('two', () => {
    jest.mock('../../../src/constants', () => ({
      platform: { IS_IOS: true }
    }));

    const { debug } = render(<MyComponent/>);
    debug();
  });
});

Este es el resultado que me meto en la consola:

  console.log
    <View>
      <Text>
        Alpha Beta 
        true
      </Text>
    </View>

      at debugDeep (node_modules/@testing-library/react-native/build/helpers/debugDeep.js:19:13)

  console.log
    <View>
      <Text>
        Alpha Beta 
        true
      </Text>
    </View>

      at debugDeep (node_modules/@testing-library/react-native/build/helpers/debugDeep.js:19:13)

Ahora, funciona si pongo jest.mock al principio del archivo, pero el problema es que simula IS_IOS con el mismo valor (es decir, IS_IOS = false):

// @ts-nocheck
import React from 'react';
import { cleanup, render } from '@testing-library/react-native';
import { MyComponent } from '../../../src/MyComponent';

jest.mock('../../../src/constants', () => ({
  platform: { IS_IOS: false }
}));

describe('MyComponent', () => {
  afterEach(() => {
    jest.resetModules();
    jest.clearAllMocks();
    cleanup();
  });

  it('one', () => {
    const { debug } = render(<MyComponent/>);
    debug();
  });

  it('two', () => {
    const { debug } = render(<MyComponent/>);
    debug();
  });
});

Como dije, se burla en ambos casos:

  console.log
    <View>
      <Text>
        Alpha Beta 
        false
      </Text>
    </View>

      at debugDeep (node_modules/@testing-library/react-native/build/helpers/debugDeep.js:19:13)

  console.log
    <View>
      <Text>
        Alpha Beta 
        false
      </Text>
    </View>

      at debugDeep (node_modules/@testing-library/react-native/build/helpers/debugDeep.js:19:13)

Probé jest.doMock, intenté agregar { {X1}}: nada de eso funciona. ¿Cómo simulo el módulo de forma diferente en cada prueba?

¡Gracias de antemano por tu tiempo!

1
Petro Ivanenko 22 ene. 2021 a las 13:02

1 respuesta

La mejor respuesta

jest.resetModules no puede afectar a los módulos que ya se han importado. Debe combinarse con require que es local a una prueba para que la jest.mock específica de la prueba la afecte.

Los módulos ES deben simularse con la propiedad mágica __esModule para que no se procesen como módulos CommonJS:

jest.mock('../../../src/constants', () => ({
  __esModule: true,
  platform: { IS_IOS: false }
}));
const { MyComponent } = require('../../../src/MyComponent');
1
Estus Flask 22 ene. 2021 a las 11:34