Jest 全局设置导致测试通过/失败不一致

mrm*_*hat 2 javascript node.js supertest jestjs

我正在尝试用玩笑测试 API。最初我所有的测试都在一个文件中并且所有测试都通过了。我想将我的测试分成不同的文件。为此,我尝试使用带有beforeEach和的全局设置文件afterEach。问题是,有时我运行测试并且它们通过,有时它们失败(每次不同的测试通过和不同的失败)。

包.json

{
"jest": {
    "verbose": true,
    "bail": false,
    "preset": "@shelf/jest-mongodb",
    "setupFilesAfterEnv": [
      "<rootDir>/jest.setup.js"
    ],
    "globals": {
      "authHeaders": {},
      "authId": null
    }
  },
}
Run Code Online (Sandbox Code Playgroud)

笑话设置.js

const app = require("./index")
const supertest = require("supertest")
const request = supertest(app)
const db = require("./src/db")
const jwtDecode = require("jwt-decode")
const getAuthToken = require("./src/utils/getAuthToken")

let token
let decodedJwt

const getAuthHeaders = token => ({
  Authorization: `Bearer ${token}`
})

beforeEach(async done => {
  //setup globals available in all tests

  token = await getAuthToken()
  token = JSON.parse(token)["access_token"]
  decodedJwt = jwtDecode(token)
  authId = decodedJwt.sub
  authHeaders = getAuthHeaders(token)

  // Ensure that we have a users collection with our test user
  // who can then call the api
  await request
    .post("/v1/users")
    .set(authHeaders)
    .send({ email: "test@example.com" })
    .expect(200)

  done()
})

afterEach(async done => {
  // Delete the users collection
  await db.instance.dropUsers()
  await db.instance.dropAgencies()

  done()
})
Run Code Online (Sandbox Code Playgroud)

用户.test.js

const app = require("../../../../index")
const supertest = require("supertest")
const request = supertest(app)
const faker = require("faker")

describe("/v1/users/:id", () => {
  test("should return an error when the users do not have a mutual agency", async done => {
      if (!authHeaders || !authId) {
        expect(true).toBe(false)
      }
      let testUserId = null
      let email = faker.internet.email()

      await request
        .post("/v1/users")
        .set(authHeaders)
        .send({ email })
        .expect(200)
        .then(({ body }) => (testUserId = body._id))

      await request
        .get("/v1/users/" + testUserId)
        .set(authHeaders)
        .expect(200)
        .then(({ body }) => {
          expect(body).toHaveProperty("error")
          expect(body.error).toHaveProperty("message")
        })

      done()
    })
})
Run Code Online (Sandbox Code Playgroud)

我可以运行上面一次,它会通过,稍后再次运行,它会失败。


编辑:

经过进一步调查,问题似乎与afterEach不删除Users集合的功能有关。beforeEach当我控制台记录文件中发出的请求的响应时,jest.setup.js我收到一条错误响应,指出给定电子邮件的用户已存在。

mrm*_*hat 5

该问题是由同时运行多个测试引起的,添加--runInBand标志(强制测试串行运行)可以修复该问题。

我的想法中的错误是我认为将用户记录添加到数据库beforeEach并删除它是安全的afterEach,而不考虑如果两个测试同时运行,其中一个测试总是会失败,因为数据库中已经存在用户。

鉴于此,我认为重构我的设置文件是一个想法,以便我的测试用户只为所有测试创建一次,但我需要考虑这样做的影响。

编辑:

我发现,runInBand通过在mongodb-memory-server测试期间切换我的 atlas 云数据库,我可以在没有该标志的情况下成功运行测试。