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 objeto esperado/recibido son iguales pero la prueba falla.

Tengo una clase contenedor A que instancia otra clase B:

class A {
  constructor(){
    this.initClassB()
  }

  private initClassB(): void{
    const options = {id : 0, ... etc}

    new B(options)        
  }
}

En mi archivo de prueba, instancio la clase A y simulo la clase B:

import { mocked } from 'ts-jest/utils';
import { ClassA } from '../ClassA';
import { ClassB } from '../ClassB';

jest.mock('../ClassB');
const mockedClassB = mocked(ClassB, true);

describe('clase B', () => {
    it('verifica si los requisitos mínimos están correctos', () => {
      const { text, url } = ClassA.props.options;

      const expectedOptions = {
        event: ClassA.event,
        id: ClassA.getDefaultSiteId(),
        loadContent: () => '',
        loader: ClassA.loader,
        text: text,
        url: url,
      };


      // la prueba falla porque lo Esperado/Recibido son idénticos
      expect(mockedClassB).toHaveBeenCalledWith(expectedOptions)

      // falla con error: serializa a la misma cadena
      expect(mockedCKTable.mock.calls[0][0]).toMatchObject(expectedOptions);
    });
});

Este es el error con el método toHaveBeenCalledWith:

enter image description here

Este es el error con el método toMatchObject:

enter image description here

Y las versiones de las dependencias:

{ 
  "@types/jest": "^26.0.24",
  "ts-jest": "^27.0.4",
  "jest": "^27.0.6",
  "typescript": "~4.1.3",
  "@types/jest": "^26.0.24"
}

¿Dónde estoy cometiendo un error?

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Hay un par de problemas con el caso de prueba proporcionado.

    En primer lugar, cuando llamas a jest.mock('../ClassB'), estás simulando todo el módulo ClassB. Por lo tanto, al intentar simular ClassB usando const mockedClassB = mocked(ClassB, true), en realidad no estás simulando la instancia de ClassB creada por initClassB() de la clase A.

    Para simular la instancia de ClassB creada por initClassB(), puedes modificar tu prueba de la siguiente manera:

    const mockedBConstructor = jest.fn();
    jest.mock('../ClassB', () => {
      return jest.fn().mockImplementation(() => {
        return { /* devuelve la instancia simulada de ClassB */ };
      });
    
      // O puedes usar el siguiente código (sin una función anónima):
      // return {
      //  __esModule: true,
      //  default: mockedBConstructor
      // };
    });
    

    Aquí, estamos simulando la instancia de ClassB devolviendo una función que actúa como el constructor de ClassB. Luego, podemos utilizar jest.fn() para simular esa función.

    En segundo lugar, cuando llamas a expect(mockedClassB).toHaveBeenCalledWith(expectedOptions), estás comprobando si mockedClassB se llama con expectedOptions. Sin embargo, dado que initClassB() crea una nueva instancia de ClassB, necesitas obtener una referencia a esa instancia en tu prueba y comprobar si esa instancia se llama con expectedOptions.

    Puedes obtener una referencia a la instancia de ClassB creada por initClassB() creando una propiedad en ClassA que contenga una referencia al objeto instanciado, de la siguiente manera:

    class A {
      private classBInstance: B;
    
      constructor() {
        this.initClassB();
      }
    
      private initClassB(): void {
        const options = { id: 0 };
    
        // almacenar la instancia de la clase B en la propiedad classBInstance
        this.classBInstance = new B(options);
      }
    }
    

    Luego, modifica tu prueba para utilizar mockedBConstructor en lugar de mockedClassB, y para comprobar si classBInstance se llama con expectedOptions, de la siguiente manera:

    it('comprobar si los requisitos mínimos están bien', () => {
      const classA = new A();
      const { text, url } = classA.props.options;
    
      const expectedOptions = {
        event: classA.event,
        id: classA.getDefaultSiteId(),
        loadContent: () => '',
        loader: classA.loader,
        text: text,
        url: url,
      };
    
      expect(mockedBConstructor).toHaveBeenCalled();
      expect(classA.classBInstance.algunMetodo).toHaveBeenCalledWith(expectedOptions);
    });
    

    Aquí, estamos comprobando si el método algunMetodo de classBInstance se llama con expectedOptions. Ten en cuenta que debes reemplazar algunMetodo con el nombre real del método en ClassB que se llama con options.

    Con estos cambios, tu prueba debería ser capaz de simular correctamente ClassB y comprobar si la instancia de ClassB creada por initClassB() se llama con las opciones esperadas.

Comments are closed.