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

标签 javascript node.js jestjs discord.js

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

/**
 * @param {Object} client - Discord Client
*/
export const getSpecificGuild = async (client) => {
    let guild = await client.guilds.fetch(GUILD_ID).catch(() => { return false });

    if (!guild) return false;

    return guild;
}

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

  • 检索有效的 Guild(返回一个 Guild 对象)。
  • 无效的公会检索(返回false)。

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

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

    const mockGuild = {
        ...
    }

    const mockClient = {
        guilds: {
            fetch: jest.fn().mockReturnValueOnce({
                catch: jest.fn().mockReturnValueOnce(false)
            })
        }
    }

    it(`should return the guild object if the guild doesn't exist.`, async () => {
        expect(await getSpecificGuild(mockClient)).toBe(false);
    });

    it(`should return the guild object if the guild does exist.`, async () => {
        expect(await getSpecificGuild(mockClient)).resolves.toBe(mockGuild);
    });
});

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

✓ should return the guild object if the guild doesn't exist. (1 ms)
✕ should return the guild object if the guild does exist.

TypeError: Cannot read properties of undefined (reading 'catch')

let guild = await client.guilds.fetch(GUILD_ID).catch(() => { return false });
                                               ^

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

最佳答案

那个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;
};

要模拟这个,您需要更新您的mockClient。您可以根据提供的公会 ID 更改 fetch 函数的行为,并有条件地返回已解决的 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);
  });
});

关于javascript - 使用 Jest 创建测试或模拟 DiscordJS Fetch/Catch,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76456535/

相关文章:

typescript - Jest (ESM) 在单元测试中从 React Native 加载文件时出现问题

php - fabric js 或 imagick 从图像中删除白色

javascript - 按数字偏移数组值,用于在 Bootstrap 列上重复 ng

javascript - 使用 mongoose 返回特定字段

javascript - 详细堆栈跟踪 : Error: Cannot find module 'stripe'

node.js - 在git root子目录中的Docker容器中以--watch模式运行Jest

javascript - 如何在没有 Browserify 的情况下测试 React 组件

javascript - 使用 Angular 2 将搜索中的对象插入数组

javascript - Backbone Marionette : put methods on instance/constructor or prototype when extending objects

javascript - 无法在 npm Ubuntu 中安装 jasmine-core