#How to mock discord.js messages or interactions for unit tests
30 messages · Page 1 of 1 (latest)
- Consider reading #how-to-get-help to improve your question!
- Explain what exactly your issue is.
- Post the full error stack trace, not just the top part!
- Show your code!
- Issue solved? Press the button!
what are you trying to mock it for? what's the purpose?
As said in the title, unit tests
Yes, but why would you unit test discord.js? You‘d need to mock the ws and rest connection, not djs itself
No it's just a fake message or interaction that's all
maybe I'll need more for the other plugins idk
There're some issues when using the real client so I was told to mock a client
And those issues come from it trying to use the real discord gateway and API. You can have it use other URLs to connect to a mocked version of the API/gateway instead
I did this for now
vi.mock("discord.js", async () => {
const actual = await vi.importActual<typeof import("discord.js")>("discord.js");
const Client = vi.fn<[ClientOptions]>((options) => ({}));
const Message = vi.fn<[client: Client, data: APIMessage]>((client, data) => ({
client,
channel: {
id: data.channel_id,
isThread: vi.fn(() => false),
},
reply: vi.fn(),
}));
const ChatInputCommandInteraction = vi.fn<
[client: Client, data: APIChatInputApplicationCommandInteraction]
>((client, data) => ({
client,
reply: vi.fn(),
}));
return { ...actual, Client, Message, ChatInputCommandInteraction };
});
It works
Yeah but I think it's a bug with the handler since it's causing the error but mocking the API if needed seems like a better idea
can you explain for me what is this 
basically made mocked classes
Mocking discord.js is pointless for unit testing. Unit testing is done by isolating one core component of a complete end to end scenario.
Let's say your scenario is "Use a ping/pong slash command", it would involves
- Catching InteractionCreate event
- Execute the corresponding callback for the ping/pong command
- Generate a reply of some sort either an embed or a simple message.
In this situation a correct unit test would be on the to test the generated response before it is sent to the Discord API.
According to the snippet you gave us I'm assuming you're using vitest to build your tests, there is a feature called extending matchers, you could use this to check if I don't know, the output of the function that create the Embed, is for exemple a correct Embed message, that have the right amount of fields, stuff like that
I faced this "How can I test my Discord bot" problem for an Integration I did at work, where tests were mandatory no matter what you do.
It was straight forward for unit test and did as I just told you.
For integration tests, it was way trickier, I mocked the Discord Client, such that when the code encounters stuff like interaction.reply that normally send data to DiscordAPI it populates an array that I can go through after my request to validate stuffs the way I want. I basically did this for messages (fetch, edit, delete etc...), channels (fetch mostly) and so on you get the point.
I guess you're trying to do integration not unit tests here, and you should probably go for something like that or maybe what I did could inspiere you something better 😄
So extensing matchers isn't gonna help, I just wanna test the command plugins that people made. Ofc I reach a point I'll have to mock the API and then it'll be harder but there's no other way since vitest causes a bug with the handler so I can't use it to import a ready client
and also if I could do it I need a command interaction to test and it'd not be possible to have unless mocked
You don't need to connect your client to the API and that's the point
What
And btw what is the bug with vitest you encounter, because I also use Vitest in the situation I explained and it worked like a charm
I'll share you a snippet if you want ✌️
It's not vitest bug it's bug with handler that's caused by using vitest
idk how it's caused since it's made with rxjs
Show us the error then, we might be able to help you
here, it's caused because one of the plugins is using useContainer to access the client
https://sourceb.in/8yjxoA5d4P
I mean the owner of the handler didn't know how to solve it so yeah
or he's just busy or smth
Oh so its related to one of your dependencies
yep