#How to mock discord.js messages or interactions for unit tests

30 messages · Page 1 of 1 (latest)

last goblet

So I tried to mock discord.js but it seems complicated, when I read the vitest docs it seems like I need to mimic every thing which you already know that discord.js has complex structures so if someone has done this please help

Here's what I did so far https://sourceb.in/x1Hh5NuCmy

prisma cloakBOT
  • 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!
soft creek

what are you trying to mock it for? what's the purpose?

fresh snow

As said in the title, unit tests

soft creek

Yes, but why would you unit test discord.js? You‘d need to mock the ws and rest connection, not djs itself

last goblet

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

soft creek
last goblet

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

last goblet
dusk abyss
last goblet

basically made mocked classes

nimble heart

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 😄

last goblet

and also if I could do it I need a command interaction to test and it'd not be possible to have unless mocked

nimble heart

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

nimble heart

I'll share you a snippet if you want ✌️

last goblet

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

nimble heart

Show us the error then, we might be able to help you

last goblet

I mean the owner of the handler didn't know how to solve it so yeah

or he's just busy or smth

nimble heart

Oh so its related to one of your dependencies

last goblet

yep