【问题标题】:Mocking a function that has a try/catch to force an error for Jest模拟具有 try/catch 的函数以强制 Jest 出错
【发布时间】:2021-06-09 11:06:04
【问题描述】:

我们为 Typescript/Express API 设置了一些开玩笑的测试。基本的GET 路由返回一些数据。

itemsRouter.get('/', async (req: Request, res: Response) => {
  try {
    const items: Item[] = await ItemService.findAll();

    res.status(200).send(items);
  } catch (e) {
    res.status(500).send(e.message);
  }
});

我们正在尝试模拟这条路线的 catch 块。只有当 try/catch 抛出错误时才会调用它。

我们如何模拟在路由中抛出错误?或者我们应该尝试模拟服务findAll 并以某种方式抛出?

该服务只是一个示例,因此它非常简单,目前只返回一些数据:

export const findAll = async (): Promise<Item[]> => Object.values(items);

【问题讨论】:

  • "或者我们应该尝试模拟服务 findAll 并以某种方式抛出?" 除了findAll 抛出之外,没有其他方法可以访问catch ,所以 - 是的,你必须以某种方式强迫它。一般来说,如果您以某种方式使try 失败,那并不能保证它与findAll throwing 一样工作。
  • 当然,所以问题是我们应该如何模拟/窥探以使尝试失败。

标签: typescript jestjs mocking try-catch ts-jest


【解决方案1】:

我将使用supertest 为您的案例编写测试。我们可以使用jest.mock() 模拟ItemService 模块,并使用.mockRejectedValueOnce() 方法模拟ItemService.findAll() 方法的拒绝值。

例如

app.ts:

import express from 'express';
import type { Request, Response } from 'express';
import type { Item } from './ItemService';
import * as ItemService from './ItemService';

const app = express();

app.get('/', async (req: Request, res: Response) => {
  try {
    const items: Item[] = await ItemService.findAll();

    res.status(200).send(items);
  } catch (e) {
    res.status(500).send(e.message);
  }
});

export { app };

ItemService.ts:

export interface Item {}

const items = { a: '1', b: '2' };

export const findAll = async (): Promise<Item[]> => Object.values(items);

app.test.ts:

import { app } from './app';
import request from 'supertest';
import * as ItemService from './ItemService';
import { mocked } from 'ts-jest/utils';

jest.mock('./ItemService');

const mItemService = mocked(ItemService);

describe('66582815', () => {
  it('should get status code 500 and an error message', (done) => {
    const mError = new Error('network');
    mItemService.findAll.mockRejectedValueOnce(mError);
    request(app)
      .get('/')
      .expect(500)
      .end((err, res) => {
        if (err) return done(err);
        expect(res.text).toBe('network');
        done();
      });
  });
});

测试结果:

 PASS  examples/66582815/app.test.ts
  66582815
    ✓ should get status code 500 and an error message (16 ms)

----------------|---------|----------|---------|---------|-------------------
File            | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
----------------|---------|----------|---------|---------|-------------------
All files       |      80 |      100 |      50 |   90.91 |                   
 ItemService.ts |      60 |      100 |       0 |     100 |                   
 app.ts         |      90 |      100 |     100 |   88.89 | 12                
----------------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        4.073 s

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-06-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-17
    • 2021-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多