Mocha/Chai 调用异步函数时预计会出现错误

Mocha/Chai expect an error when calling an async function

我正在使用 mocha / chai 来做一些测试。 如果使用相同的参数调用,该函数应该抛出 new Error

函数:

创建一个新用户并将其保存到我的数据库 (mongoDB),如果不存在具有相同 discord id 的用户。 fetchUser(disc_id)使用 mongoose 中的 findOne() 搜索现有用户。

async function createUser(disc_id, moodleToken) {
    const profileData = await fetchUser(disc_id);
    if (profileData) {
        throw new Error("The account already exist in the database!");
    }
    
    const newUser = profileModel.create({
        discord_id: disc_id,
        moodle_token: moodleToken,
    }, (err) => {
            if (err) throw err;
            console.log("Document created!")
    })
    return newUser;
};

fetchUser

function fetchUser (disc_id) {
    return profileModel.findOne({ discord_id: disc_id });
}

测试

我正在使用 sinon 创建“测试数据库”。以下测试顺利通过

describe("Create user", function () {
        it("Should create a new user in database if the discord id is not in the database", async function () {
            const discord_id = "2341243451";
            const moodle_token = "fwefw89fwefHFEF0F90ls";
            
            sinon.stub(profileSchema, "findOne").returns(null);
            sinon.stub(profileSchema, "create").returns({
                discord_id, moodle_token
            });
            
            const returnedUser = await createUser(discord_id, moodle_token);
            
            expect(returnedUser.discord_id).to.equal(discord_id);
        })

这测试是否可以创建一个新用户并将其保存到我的数据库中,如果没有现有用户具有相同的 discord ID。

如果我想做相反的测试,创建一个新用户,但当前用户已经存在相同的id,它应该抛出错误:“该帐户已经存在于数据库中! "

it("Should throw an error if there exists a user with that discord id", async () => {
            const discord_id = "2341243451";
            const moodle_token = "fwefw89fwefHFEF0F90ls";
            
            const fakeObject = {
                discord_id: discord_id,
                moodle_token: moodle_token
            };

            sinon.stub(profileSchema, "findOne").returns(fakeObject);
            sinon.stub(profileSchema, "create").returns({ discord_id, moodle_token })

我试过没有成功:

            try {
                await createUser(discord_id, moodle_token);
            } catch (err) {
                console.log(err);
                expect(err).to.equal("The account already exist in the database!");
            }
            
            expect(async function () { await createUser(discord_id, moodle_token); }).to.throw("The account already exist in the database!");
            expect(() => { createUser(discord_id, moodle_token)}).to.throw("The account already exist in the database!");
            rejects(async () => { await createUser(discord_id, moodle_token); })

我应该如何测试这样的功能?

我找到了解决问题的方法,我将 createUser() 重组为:

async function createUser(disc_id, moodleToken) {
    const profileData = await fetchUser(disc_id);
    if (profileData) {
        throw TypeError("The account already exist in the database!");
    }
    const newUser = new profileModel({
        discord_id: disc_id,
        moodle_token: moodleToken,
    })
    await newUser.save();
    return newUser;
}

如果是这样的话测试通过:

it("Should throw an error if there exists a user with that discord id", async () => {
            const discord_id = "2341243451";
            const moodle_token = "fwefw89fwefHFEF0F90ls";
            
            const fakeObject = {
                discord_id: "2341243451",
                moodle_token: "fwefw89fwefHFEF0F90ls"
            };

            sinon.stub(profileSchema, "findOne").returns(fakeObject);

            await createUser(discord_id, moodle_token).catch((error) => {
                expect(error.message).to.equal("The account already exist in the database!")
            })

不知道这样做是否正确,但如果我将 sinon.stub 更改为 return null 测试将无法通过。

所以我想这是一种处理它的方法。