Edit: Answered.
I'm relatively new to Jest and TDD and I'm trying to set up a backend for an app I'm creating with React Native. I'm using TDD and trying to work on the login/register user endpoint. When I send a request via Postman to create a new user, it goes through with a 200 response and I end up with a new user in the MongoDB collection.
However, when I run the test with Jest, it returns a 400 response. I can't seem to figure out why this is happening. The first 2 tests in this suite pass, only the last one fails.
users.test.js
const request = require("supertest")
const {User} = require("../../models/user")
let server
const users = "/api/users"
describe(`${users}`, () => {
beforeEach(() => server = require("../../index"))
afterEach(async() => {
await server.close()
await User.remove({})
})
let userEmail = "user1@a.a"
let validUser = {username: "user1", email: userEmail, password: "1234567"}
const exec = () => request(server).post(users).send(validUser)
describe("/POST", () => {
it("should return 400 if invalid data is given", async() => {
validUser.email = "user1"
const res = await exec()
expect(res.status).toBe(400)
})
it("should return 400 if user with email already exists", async() => {
validUser.email = userEmail
await exec()
const res = await exec()
expect(res.status).toBe(400)
})
it("should return 200 and generate new user if valid information is given", async() => {
const res = await exec()
const user = await User.find({username: validUser.username})
expect(user).not.toBeNull()
expect(res.status).toBe(200)
})
})
})
users.js
const _ = require("lodash")
const bcrypt = require("bcrypt")
require("mongoose")
const express = require("express")
const router = express.Router()
const {User, validate} = require("../models/user")
router.post("/", async(req, res) => {
const {error} = validate(req.body)
if(error) return res.status(400).send(error.details[0].message)
let checkUser = await User.findOne({email: req.body.email})
if(checkUser) return res.status(400).send("User with that email already exists.")
const user = new User(_.pick(req.body, ["username", "email", "password"]))
const salt = await bcrypt.genSalt(10)
user.password = await bcrypt.hash(user.password, salt)
await user.save()
res.send(user)
})
module.exports = router
Edit: Mutating the validUser object was causing problems in subsequent tests, as pointed out in the comments. Added userEmail variable as a valid email and added await to User.find(). After mutating the object in the first test, I set the validUser.email property back to the valid email, which fixed the problem.
Mutating the validUser object as Estus Flask pointed out was causing the error. Setting the validUser.email property back to it's original valid email string after the 1st test fixed the problem. validUser being assigned in beforeEach also works.