Глобальная настройка Jest приводит к непоследовательному прохождению теста / провалу - PullRequest
0 голосов
/ 26 января 2020

Я пытаюсь проверить API с шуткой. Первоначально все мои тесты, где один файл и все тесты, где проходили. Я хотел разделить свои тесты на разные файлы. Для этого я пытаюсь использовать глобальный установочный файл с beforeEach и afterEach. Проблема в том, что иногда я запускаю тесты, и они проходят, а иногда они терпят неудачу (разные тесты и разные неудачи каждый раз).

package. json

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

jest. setup. 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()
})

users.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()
    })
})

Я могу запустить приведенное выше один раз, и через несколько секунд оно пройдет и снова запустится, и произойдет сбой.


Редактировать:

После дальнейшего исследования кажется, что проблема связана с тем, что функция afterEach не удаляет коллекцию Users. Когда я консоль регистрирую ответ на запрос, сделанный в beforeEach в файле jest.setup.js, я получаю сообщение об ошибке, в котором говорится, что пользователь для данного электронного письма уже существует.

1 Ответ

0 голосов
/ 29 января 2020

Проблема была вызвана несколькими тестами, запущенными одновременно, добавление флага --runInBand (который заставляет тест выполняться последовательно) устраняет проблему.

Ошибка в моем мышлении заключалась в том, что я предположил, что это было безопасно добавить пользовательскую запись в базу данных beforeEach и удалить ее afterEach, не считая, что, если два теста будут выполняться одновременно, один из них всегда будет неудачным, поскольку пользователь уже существует в базе данных.

В свете этого я думаю, что было бы неплохо реорганизовать мой установочный файл так, чтобы мой тестовый пользователь создавался только один раз для всех тестов, но мне нужно учесть последствия этого.

РЕДАКТИРОВАТЬ:

Я обнаружил, что могу успешно выполнить тестирование без флага runInBand, переключив мою облачную базу данных Atlas в пользу mongodb-memory-server во время тестов.

...