我正在尝试用笑话来测试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: "[email protected]" })
.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
中进行控制台日志记录时,收到的错误响应是说给定电子邮件的用户已经存在。
此问题是由同时运行多个测试引起的,添加--runInBand
标志(强制测试以串行方式运行可解决此问题。
我的想法是,我认为可以安全地将用户记录添加到数据库beforeEach
中并将其删除afterEach
,而无需考虑如果两个测试同时运行,那么一个测试总是会失败,因为用户已经数据库中存在。
鉴于此,我认为重构我的安装文件是一个主意,这样我的测试用户只为所有测试创建一次,但是我需要考虑这样做的含义。
[我发现我可以通过在测试过程中将Atlas云数据库切换为runInBand
来成功运行没有mongodb-memory-server
标志的测试。