重用Jest单元测试

时间:2018-07-16 22:43:34

标签: javascript unit-testing jestjs

我正在尝试使用Jest测试几个数据库实现。为了帮助测试这些实现,我首先想出了一套针对这两种实现都有望实现的API的单元测试。

我目前正在努力将这两种实现传递给测试套件。

下面是最简单形式的(虚拟)MongoDB实现:

class MongoDB {
  async query () {
    console.warn(`This is a dummy function.`)
  }

  async connect () {
    // The real connect takes some time..instead we just simulate it
    await new Promise((resolve, reject) => {
      setTimeout(resolve, 300)
    })
  }
}

这是我的测试的一小段:

let db
beforeAll(async () => {
  db = new MongoDB()
  await db.connect()
  console.log(`mongoDB ready`)
})

async function testDB (db) {
  describe('Basic', async () => {
    test('Valid instance', async () => {
      expect(db).toBeTruthy()
      expect(db.query).toBeTruthy()
    })
  })
}

describe('Tests', async () => {
  console.log(`Running testDB`)
  testDB(db) // Have also unsuccessfully tried changing this to: return testDB(db)
})

我使用这种方法的目标是将我所有的测试包装在testDB函数中,并通过各种实现对其进行简单地调用。例如testDB(new MongoDB())testDB(new MemoryDB()),依此类推。

但是,这似乎不起作用。 上面的代码导致错误,说明:

  ● Tests › Basic › Valid instance

    expect(received).toBeTruthy()

    Expected value to be truthy, instead received
      undefined

console.log语句的顺序似乎暗示测试在 db初始化之前正在运行。

  console.log mongo.test.js:20
    Running testDB

  console.log mongo.test.js:7
    mongoDB ready

整个示例以及结果输出可以为reproduced on repl.it

我如何重用单元测试来测试多个实现,而不必重复测试并维护两个版本?

1 个答案:

答案 0 :(得分:0)

今天也面临同样的需求。这是从打字稿改编的方法,但是您知道了:

// common/service.test.js
export const commonServiceTests = (name, impl) => {
  describe(`Common tests for ${implName}`, () => {
    // pile your tests here
    test('test1', () => { ... });
    test('test2', () => { ... });
    test('test3', () => { ... });
  });
}

// just to avoid warning, that no tests in test file
describe('Common tests for CommonService implementations', () => {
  test('should be used per implementation', () => {});
});

对于您的每个实现:

// inmemory/service.test.js
import { commonServiceTests } from '../common/service.test';
import ...; // your implementation here

const myInMemoryService = ...; // initialize it

commonServiceTests('InMemory', myInMemoryService);

然后common/service.test.js中定义的所有测试将在每个实施测试中执行。

如果您的初始化是async(很有可能),那么共享测试也应该是async。然后:

// common/service.test.js
export const commonServiceTests = (name, impl: Promise) => {
  describe(`Common tests for ${implName}`, () => {
    // pile your async tests here
    test('test1', async () => {
      const svc = await impl;
      return await svc.doSomthingPromisy();
    });
    test('test2', () => { ... });
    test('test3', () => { ... });
  });
}