Búsqueda de sitios web

javascript - Cómo verificar un mensaje de error mediante jest mock para lanzar un error dentro de un bloque catch


Necesito ayuda para hacer un mock en Jest de throw Error(JSON.stringify(studentErrorRes));. No puedo hacer un mock correctamente del bloque catch en Jest, puedo hacer una verificación parcial de que se lanza un error. Puedo hacer el bloque try sin ningún problema. Normalmente, cuando hay un error hago mock usando .mockRejectedValue, pero no funciona en este caso. ¿Alguien puede ayudarme, cómo debería hacer este mock?

Cuando bromeo con un mock, puedo verificar con éxito que se está lanzando un error, pero no puedo verificar cuál sería el mensaje de error exacto. Si tengo más claves dentro de const studentErrorRes, ¿cómo debería verificar en mi mock que todas mis claves tienen los valores correctos como se espera? Espero no estar sobrepensando.

import { SNSEvent } from 'aws-lambda';

export const studentAPIGetHandler = async (event: SNSEvent): Promise<any> => {
  try {
    const studentID = event.studentInfo.studentID;
    const studentPortal = StudentService.getStudentInfo(studentID);
  } catch (error) {
    const studentErrorRes = {
      apiName: SuudentAPIName.Student_Message,
      myMessage: 'Unable to get student API response',
    };
    logger.error(studentErrorRes.myMessage, error);
    throw Error(JSON.stringify(studentErrorRes));
  }
};

Parte del caso de prueba para el bloque catch

it("Catch block test for error", async () => {


    try {
        await studentAPIGetHandler(event);
    } catch(e) {
        expect(e).toThrowError; 
// this verifies that error is thrown , but not exact error message

    }

    });

Respuesta #1

Aquí está la solución del test de unidad:

index.ts:

import { StudentService } from './student.service';

type SNSEvent = any;
const SuudentAPIName = { Student_Message: 'Student_Message' };
const logger = console;

export const studentAPIGetHandler = async (event: SNSEvent): Promise<any> => {
  try {
    const studentID = event.studentInfo.studentID;
    const studentPortal = StudentService.getStudentInfo(studentID);
  } catch (error) {
    const studentErrorRes = {
      apiName: SuudentAPIName.Student_Message,
      myMessage: 'Unable to get student API response',
    };
    logger.error(studentErrorRes.myMessage, error);
    throw Error(JSON.stringify(studentErrorRes));
  }
};

student.service.ts:

export class StudentService {
  public static getStudentInfo(id) {
    return {} as any;
  }
}

index.test.ts:

import { studentAPIGetHandler } from './';
import { StudentService } from './student.service';

describe('59871106', () => {
  afterEach(() => {
    jest.restoreAllMocks();
  });
  it('should get student info', async () => {
    jest.spyOn(StudentService, 'getStudentInfo').mockReturnValueOnce({});
    const mEvent = { studentInfo: { studentID: 1 } };
    await studentAPIGetHandler(mEvent);
    expect(StudentService.getStudentInfo).toBeCalledWith(1);
  });

  it('should handle error', async () => {
    const mError = new Error('some error');
    jest.spyOn(StudentService, 'getStudentInfo').mockImplementationOnce(() => {
      throw mError;
    });
    jest.spyOn(console, 'error');
    const mEvent = { studentInfo: { studentID: 1 } };
    await expect(studentAPIGetHandler(mEvent)).rejects.toThrowError(
      JSON.stringify({ apiName: 'Student_Message', myMessage: 'Unable to get student API response' }),
    );
    expect(console.error).toBeCalledWith('Unable to get student API response', mError);
    expect(StudentService.getStudentInfo).toBeCalledWith(1);
  });
});

Resultados de la prueba unitaria con informe de cobertura:

 PASS  src/stackoverflow/59871106/index.test.ts (12.591s)
  59871106
    ✓ should get student info (10ms)
    ✓ should handle error (12ms)

  console.error node_modules/jest-mock/build/index.js:860
    Unable to get student API response Error: some error
        at /Users/ldu020/workspace/github.com/mrdulin/jest-codelab/src/stackoverflow/59871106/index.test.ts:16:20
        at Generator.next (<anonymous>)
        at /Users/ldu020/workspace/github.com/mrdulin/jest-codelab/src/stackoverflow/59871106/index.test.ts:8:71
        at new Promise (<anonymous>)
        at Object.<anonymous>.__awaiter (/Users/ldu020/workspace/github.com/mrdulin/jest-codelab/src/stackoverflow/59871106/index.test.ts:4:12)
        at Object.it (/Users/ldu020/workspace/github.com/mrdulin/jest-codelab/src/stackoverflow/59871106/index.test.ts:15:40)
        at Object.asyncJestTest (/Users/ldu020/workspace/github.com/mrdulin/jest-codelab/node_modules/jest-jasmine2/build/jasmineAsyncInstall.js:102:37)
        at resolve (/Users/ldu020/workspace/github.com/mrdulin/jest-codelab/node_modules/jest-jasmine2/build/queueRunner.js:43:12)
        at new Promise (<anonymous>)
        at mapper (/Users/ldu020/workspace/github.com/mrdulin/jest-codelab/node_modules/jest-jasmine2/build/queueRunner.js:26:19)
        at promise.then (/Users/ldu020/workspace/github.com/mrdulin/jest-codelab/node_modules/jest-jasmine2/build/queueRunner.js:73:41)
        at process._tickCallback (internal/process/next_tick.js:68:7)

--------------------|----------|----------|----------|----------|-------------------|
File                |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
--------------------|----------|----------|----------|----------|-------------------|
All files           |    92.31 |      100 |    66.67 |    91.67 |                   |
 index.ts           |      100 |      100 |      100 |      100 |                   |
 student.service.ts |       50 |      100 |        0 |       50 |                 3 |
--------------------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        14.685s

Código fuente: https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/59871106