首页 > 解决方案 > 开玩笑测试猫鼬唯一字段会创建重复项

问题描述

尝试使用 jest 测试 nodejs 后端。
此测试通过 70% 的时间,但有时会失败。

我的测试:
两者userInputcopycatUserInput保存到数据库中并创建一个重复的电子邮件。

test("Register with the same email twice shoud throw an error.", async () => {
    const userInput: ICreateUserInput = {
        email: "same-email@gmail.com",
        username: "username",
        password: "tesT$1234",
    };

    const copycatUserInput: ICreateUserInput = {
        email: "same-email@gmail.com",
        username: "differentUsername",
        password: "tesT$1234",
    };

>    await registerUser(userInput);
>    await expect(registerUser(copycatUserInput)).rejects.toThrow(/(Email address is already exists)/);
});

失败原因:

expect(received).rejects.toThrow()

Received promise resolved instead of rejected
Resolved to value: {"token": "eyJhb...

这是我的猫鼬模式:
用户名和电子邮件字段都是唯一的

const schemaOptions: SchemaOptions = { timestamps: true };

const userSchema = new Schema(
    {
        username: {
            type: String,
            required: true,
            unique: true,
        },

        email: {
            type: String,
            required: true,
            unique: true,
            lowercase: true,
        },

        password: {
            type: String,
            required: true,
        },

        status: String,
    },
    schemaOptions,
);

export default model<IUser>("User", userSchema);

和 registerUser 功能:

export default async (registerInput: ICreateUserInput): Promise<ILoginUserResult> => {
    /**
     * validate props.
     */
    if (!isEmail(registerInput.email)) throw new Error("Email address is not valid.");
    if (!isValidUsername(registerInput.username)) throw new Error("Username is not valid.");
    if (!isStrongPassword(registerInput.password)) throw new Error("Password is not valid.");

    /**
     * gnerate hashed password.
     */
    try {
        const hashPassword = await createHashedPassword(registerInput.password);

        /**
         * create new user.
         */
        const doc: ICreateUserInput = {
            email: registerInput.email,
            username: registerInput.username,
            password: hashPassword,
            status: registerInput.status ? registerInput.status : "",
        };

        /**
         * save the user in the database.
         */
        const user = await new User(doc).save();

        return {
            user,
            token: getAuthToken(user),
        };
    } catch (error) {
        /**
         * throws a duplicate email error.
         */
        if (error.message && `${error.message}`.includes("email_1 dup key:")) {
            throw new Error("Email address is already exists");
        }

        /**
         * throws a duplicate username error.
         */
        if (error.message && `${error.message}`.includes("username_1 dup key:")) {
            throw new Error("Username is already exists");
        }

        /**
         * may be that mongoose or bcrypt are throwing..
         */
        Logger.error(`auth.registerUser => ${error}`);
        throw new Error(`Error: Failed to register user: ${error.message}`);
    }

我还进入useCreateIndex: true了连接选项
并尝试等待创建索引:

user.once("index", () => {
    user = await new User(doc).save();
});

谢谢您的帮助

编辑:
最终分别运行测试,在每个测试套件(beforeAll)上建立新的连接可以解决问题:(

"scripts": {
    "test": "jest --runInBand",
},

标签: javascriptnode.jsmongodbmongoosejestjs

解决方案


推荐阅读