简体   繁体   中英

jest testing discord bot commands

So I have a file that I use module exports on and it has 4 fields among which an execute field that takes 2 args and is essentially a function. It doesn't return anything instead it uses discord.js and runs this message.channel.send('Pong'); . I want to test this using jest How do I: 1 - Make sure that the message.channel.send was called with 'Pong' as args 2 - How do I mock it so it doesnt actually call it (i just want to make sure that the text inside of it, like the actual argument is 'Pong' since calling it won't work due to the lack of a proper message object)

I can access the actual command and execute it but I am unsure as to how to check the contents of message.channel.send . The message object cannot be reconstructed by me so that might also need mocking.

I'm using discord.js but that shouldn't really matter.

I will also have to test commands that feature functions that do have returns so how should I go about them?

I'm actually working on a Discord.js mocking library, but until that's done you can do this:

const Discord = require('discord.js')

// replace this with whatever the execute command is
// e.g. const ping = require('./commands/ping').execute
const ping = async (message, args) => {
  message.channel.send('Pong')
}

// a counter so that all the ids are unique
let count = 0

class Guild extends Discord.Guild {
  constructor(client) {
    super(client, {
      // you don't need all of these but I just put them in to show you all the properties that Discord.js uses
      id: count++,
      name: '',
      icon: null,
      splash: null,
      owner_id: '',
      region: '',
      afk_channel_id: null,
      afk_timeout: 0,
      verification_level: 0,
      default_message_notifications: 0,
      explicit_content_filter: 0,
      roles: [],
      emojis: [],
      features: [],
      mfa_level: 0,
      application_id: null,
      system_channel_flags: 0,
      system_channel_id: null,
      widget_enabled: false,
      widget_channel_id: null
    })
    this.client.guilds.cache.set(this.id, this)
  }
}

class TextChannel extends Discord.TextChannel {
  constructor(guild) {
    super(guild, {
      id: count++,
      type: 0
    })
    this.client.channels.cache.set(this.id, this)
  }

  // you can modify this for other things like attachments and embeds if you need
  send(content) {
    return this.client.actions.MessageCreate.handle({
      id: count++,
      type: 0,
      channel_id: this.id,
      content,
      author: {
        id: 'bot id',
        username: 'bot username',
        discriminator: '1234',
        bot: true
      },
      pinned: false,
      tts: false,
      nonce: '',
      embeds: [],
      attachments: [],
      timestamp: Date.now(),
      edited_timestamp: null,
      mentions: [],
      mention_roles: [],
      mention_everyone: false
    })
  }
}

class Message extends Discord.Message {
  constructor(content, channel, author) {
    super(channel.client, {
      id: count++,
      type: 0,
      channel_id: channel.id,
      content,
      author,
      pinned: false,
      tts: false,
      nonce: '',
      embeds: [],
      attachments: [],
      timestamp: Date.now(),
      edited_timestamp: null,
      mentions: [],
      mention_roles: [],
      mention_everyone: false
    }, channel)
  }
}

const client = new Discord.Client()
const guild = new Guild(client)
const channel = new TextChannel(guild)

// the user that executes the commands
const user = {id: count++, username: 'username', discriminator: '1234'}

describe('ping', () => {
  it('sends Pong', async () => {
    await ping(new Message('ping', channel, user))
    expect(channel.lastMessage.content).toBe('Pong')
  })
})

You also need to put testEnvironment: 'node' in your jest configuration (see this issue ).


Edit

You can also use Discord.SnowflakeUtil.generate() to generate an id if you need to obtain things like the timestamp.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM