0

我试图在我的异步函数中捕获错误并使用 jest 测试这些函数。

import Db from './lib/db'
const db = new Db()

export async function example (id) {
  await db.connect().catch(err => console.error(err))
  const Data = db.connection.collection('data')

  return Data.updateOne(
    { id },
    { $set: { anything: 'else' } }
  ).catch(err => console.error(err))
}

但是测试返回给我错误:

TypeError: db.connect(...).catch 不是函数

那么我做错了什么?测试还是捕捉?

test('should call mongoDB updateOne() method', async () => {
  // SETUP
  let Data = db.connection.collection('data')
  Data.updateOne = jest.fn()
  // EXECUTE
  expect.assertions(1)
  await example({
    id: 'id'
  }).then((res) => {
    // VERIFY
    expect(Data.updateOne).toHaveBeenCalled()
  })
})
4

1 回答 1

0

这是解决方案:

Db.ts

import console = require('console');

export class Db {
  public connection = {
    collection(model: string) {
      return {
        async updateOne(...args) {
          console.log('update one');
        }
      };
    }
  };
  public async connect() {
    console.log('connect db');
  }
}

example.ts

import { Db } from './Db';

const db = new Db();

export async function example(id) {
  await db.connect().catch(err => console.error(err));
  const Data = db.connection.collection('data');

  return Data.updateOne({ id }, { $set: { anything: 'else' } }).catch(err => console.error(err));
}

example.spec.ts

import { example } from './example';
import { Db } from './Db';

jest.mock('./Db.ts', () => {
  const collectionMocked = {
    updateOne: jest.fn()
  };
  const connectionMocked = {
    collection: jest.fn(() => collectionMocked)
  };

  const DbMocked = {
    connect: jest.fn(),
    connection: connectionMocked
  };
  return {
    Db: jest.fn(() => DbMocked)
  };
});

const db = new Db();

describe('example', () => {
  test('should call mongoDB updateOne() method', async () => {
    const Data = db.connection.collection('data');
    (db.connect as jest.MockedFunction<any>).mockResolvedValueOnce({});
    (Data.updateOne as jest.MockedFunction<any>).mockResolvedValueOnce('mocked value');
    const actualValue = await example('1');
    expect(actualValue).toBe('mocked value');
    expect(Data.updateOne).toHaveBeenCalledWith({ id: '1' }, { $set: { anything: 'else' } });
  });
});

带有覆盖率报告的单元测试结果:

PASS  src/stackoverflow/57515192/example.spec.ts
  example
    ✓ should call mongoDB updateOne() method (6ms)

------------|----------|----------|----------|----------|-------------------|
File        |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
------------|----------|----------|----------|----------|-------------------|
All files   |       75 |      100 |    33.33 |      100 |                   |
 example.ts |       75 |      100 |    33.33 |      100 |                   |
------------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        3.336s, estimated 6s

这是完成的演示:https ://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/57515192

于 2019-09-24T06:21:41.483 回答