我已经创建了一个DiscordJS机器人,我正在try 使用JestJS实现自动化测试.以下是我try 用来创建测试的函数之一:

/**
 * @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;
}

我现在不能解决的问题是try 为这两种场景创建测试:

  • 检索有效的Guild(返回Guild对象).
  • 无效的Guild检索(返回100).

以下是我的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相关问答推荐

如何在JavaScript中通过一次单击即可举办多个活动

为什么我达到了时间限制!?LeetCode链接列表循环(已解决,但需要解释!)

了解Node.js中的EventEums和浏览器中的addEventEums之间的关系

如何从一个列表中创建一个2列的表?

成功完成Reducers后不更新状态

WebGL 2.0无符号整数输入变量

如何在输入元素中附加一个属性为checkbox?

Ember.js 5.4更新会话存储时如何更新组件变量

S文本内容和值不必要的不同

try 使用javascript隐藏下拉 Select

Eval vs函数()返回语义

当代码另有说明时,随机放置的圆圈有时会从画布上消失

图表4-堆叠线和条形图之间的填充区域

如何在Java脚本中对数据进行签名,并在PHP中验证签名?

如何在独立的Angular 应用程序中添加Lucide-Angel?

react 路由DOM有条件地呈现元素

用Reaction-RT-Chart创建实时条形图

如何在Reaction中清除输入字段

如何压缩图像并将其编码为文本?

如何设置时间选取器的起始值,仅当它获得焦点时?