英文:
Create tests or Mock DiscordJS Fetch/Catch using Jest
问题
I have translated the non-code part of your text. Here it is:
"I have created a DiscordJS Bot and I am trying to implement automated tests using JestJS. Here's one of the functions I am trying to create tests with:
The problem that I can't solve right now is trying to create tests for both scenarios:
- Retrieving a valid Guild (which returns a Guild Object).
- Invalid Guild retrieval (which returns false).
Below is the current version of my sample.test.js
file:
I found it difficult to mock the fetch/catch
part of the program. Because fetch
ends if the retrieval is successful and doesn't continue to the catch
part unless it runs an error (like a try/catch
would do). Upon running the tests, it displays the following:
Forgive me if my Jest implementation is wrong and would really appreciate everyone's assistance."
Please note that the code remains untranslated as requested. If you have any questions or need further assistance with the code, feel free to ask.
英文:
I have created a DiscordJS Bot and I am trying to implement automated tests using JestJS. Here's one of the functions I am trying to create tests with:
/**
* @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;
}
The problem that I can't solve right now is trying to create tests for both scenarios:
- Retrieving a valid Guild (which returns a Guild Object).
- Invalid Guild retrieval (which returns false).
Below is the current version of my sample.test.js
file:
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);
});
});
I found it difficult to mock the fetch/catch
part of the program. Because fetch
ends if the retrieval is successful and doesn't continue to the catch
part unless it runs an error (like a try/catch
would do). Upon running the tests, it displays the following:
✓ 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 });
^
Forgive me if my Jest implementation is wrong and would really appreciate everyone's assistance.
答案1
得分: 4
以下是翻译好的内容:
那个`catch`是Promise实例上的一个方法,你不应该对它进行模拟。你只应该模拟`guilds.fetch()`。
此外,你的`getSpecificGuild()`函数目前不接受公会ID,所以我对它进行了更新。我认为`client.guilds.fetch()`永远不会返回假值,所以你可以移除它:
```js
export const getSpecificGuild = async (guildId, client) => {
let guild = await client.guilds.fetch(guildId).catch(() => {
return false;
});
return guild;
};
要模拟这个,你需要更新你的mockClient
。你可以根据提供的公会ID改变fetch
函数的行为,有条件地返回一个已解决的Promise或一个被拒绝的Promise。
describe('测试getSpecificGuild函数', () => {
beforeEach(() => {
jest.clearAllMocks();
});
const mockGuild = { ... };
const VALID_GUILD_ID = '804214837842837';
const mockClient = {
guilds: {
fetch: jest.fn().mockImplementation((guildId) => {
// 有效的公会检索
if (guildId === VALID_GUILD_ID)
return Promise.resolve(mockGuild);
// 无效的公会检索
else
return Promise.reject(new Error('公会未找到'));
}),
},
};
it(`如果公会存在,应该返回公会对象。`, async () => {
// 使用await时不需要使用"resolves.toBe()"
expect(await getSpecificGuild(VALID_GUILD_ID, mockClient)).toBe(mockGuild);
});
it(`如果公会不存在,应该返回false。`, async () => {
expect(await getSpecificGuild('12345', mockClient)).toBe(false);
});
});
希望这能帮助你!如果有任何其他问题,请随时提问。
英文:
That catch
is a method on a Promise instance, you should not mock that. You should only mock guilds.fetch()
.
Also, your getSpecificGuild()
function doesn't accept a guild ID at the moment, so I updated it. And I don't think client.guilds.fetch()
will ever return falsy values, so you can remove that too:
export const getSpecificGuild = async (guildId, client) => {
let guild = await client.guilds.fetch(guildId).catch(() => {
return false;
});
return guild;
};
To mock this, you need to update your mockClient
. You could change the behaviour of the fetch
function based on the provided guild ID and conditionally return either a resolved Promise or a rejected 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);
});
});
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论