使用 Jest 创建测试或模拟 DiscordJS Fetch/Catch

Cif*_*Cif 3 javascript node.js jestjs discord.js

我创建了一个DiscordJS Bot,并尝试使用JestJS实现自动化测试。这是我尝试创建测试的函数之一:

\n
/**\n * @param {Object} client - Discord Client\n*/\nexport const getSpecificGuild = async (client) => {\n    let guild = await client.guilds.fetch(GUILD_ID).catch(() => { return false });\n\n    if (!guild) return false;\n\n    return guild;\n}\n
Run Code Online (Sandbox Code Playgroud)\n

我现在无法解决的问题是尝试为这两种情况创建测试:

\n
    \n
  • 检索有效的 Guild(返回Guild对象)。
  • \n
  • 无效的 Guild 检索(返回false)。
  • \n
\n

以下是我的文件的当前版本sample.test.js:

\n
describe(\'Test getSpecificGuild Function\', () => {\n    beforeEach(() => {\n        jest.clearAllMocks();\n    });\n\n    const mockGuild = {\n        ...\n    }\n\n    const mockClient = {\n        guilds: {\n            fetch: jest.fn().mockReturnValueOnce({\n                catch: jest.fn().mockReturnValueOnce(false)\n            })\n        }\n    }\n\n    it(`should return the guild object if the guild doesn\'t exist.`, async () => {\n        expect(await getSpecificGuild(mockClient)).toBe(false);\n    });\n\n    it(`should return the guild object if the guild does exist.`, async () => {\n        expect(await getSpecificGuild(mockClient)).resolves.toBe(mockGuild);\n    });\n});\n
Run Code Online (Sandbox Code Playgroud)\n

我发现很难模拟fetch/catch该程序的部分。因为fetch如果检索成功则结束,并且不会继续该catch部分,除非它运行错误(就像 atry/catch会做的那样)。运行测试后,它显示以下内容:

\n
\xe2\x9c\x93 should return the guild object if the guild doesn\'t exist. (1 ms)\n\xe2\x9c\x95 should return the guild object if the guild does exist.\n\nTypeError: Cannot read properties of undefined (reading \'catch\')\n\nlet guild = await client.guilds.fetch(GUILD_ID).catch(() => { return false });\n                                               ^\n
Run Code Online (Sandbox Code Playgroud)\n

如果我的 Jest 实现有误,请原谅我,非常感谢大家的帮助。

\n

Zso*_*ros 5

这catch是 Promise 实例上的一个方法,你不应该嘲笑它。你应该只嘲笑guilds.fetch()。

另外,你的getSpecificGuild()函数目前不接受公会 ID,所以我更新了它。我认为永远不会client.guilds.fetch()返回虚假值,因此您也可以将其删除:

export const getSpecificGuild = async (guildId, client) => {
  let guild = await client.guilds.fetch(guildId).catch(() => {
    return false;
  });

  return guild;
};
Run Code Online (Sandbox Code Playgroud)

要模拟这一点,您需要更新您的mockClient. fetch您可以根据提供的公会 ID更改函数的行为,并有条件地返回已解决的 Promise 或已拒绝的 Promise。

describe('Test getSpecificGuild Function', () => {
  beforeEach(() => {
    jest.clearAllMocks();
  });

  const mockGuild = { ... };
  const VALID_GUILD_ID = '804214837842837';

  const mockClient = {
    guilds: {
      fetch: jest.fn().mockImplementation((guildId) => {
        // Valid guild retrieval
        if (guildId === VALID_GUILD_ID) 
          return Promise.resolve(mockGuild);

        // Invalid guild retrieval
        else
          return Promise.reject(new Error('Guild not found'));
      }),
    },
  };

  it(`should return the guild object if the guild does exist.`, async () => {
    // you don't need "resolves.toBe()"" with await
    expect(await getSpecificGuild(VALID_GUILD_ID, mockClient)).toBe(mockGuild);
  });

  it(`should return false if the guild doesn't exist.`, async () => {
    expect(await getSpecificGuild('12345', mockClient)).toBe(false);
  });
});
Run Code Online (Sandbox Code Playgroud)