dismock

module
v2.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 11, 2021 License: MIT

README ยถ

dismock

GitHub Workflow Status (branch) Test Coverage Go Report Card PkgGoDev License


Dismock is a library that aims to make mocking Discord's API requests as easy as winking. No more huge integration tests that require a bot on some private server with little to no debug information.

Although, dismock uses arikawa as a foundation for its data types, it isn't limited to a specific discord library.

Getting Started

Basic Testing

You can create a mock by calling the method that corresponds to the API request you made in your code. Below is a simple example of a ping command, and it's unit test.

func (b *Bot) Ping(e *gateway.MessageCreateEvent) (error) {
    _, err := b.Ctx.SendText(e.ChannelID, "๐Ÿ“")
    if err != nil {
        return err
    }

    _, err := b.Ctx.SendText(e.ChannelID, "Pong!")
    return err
}
func TestBot_Ping(t *testing.T) {
    // you can also mock a Session by using dismock.NewSession(t), or dismock.New(t) 
    // to only create a Mocker
    m, s := dismock.NewState(t)
    
    // at the end of every test m.Eval() must be called, to check that all 
    // handlers were invoked
    defer m.Eval()

    var channelID discord.ChannelID = 123

    m.SendText(discord.Message{
        // the doc of every mock specifies what fields are required, all other
        // fields not relevant to your test can be omitted
        ChannelID: channelID,
        Content: "๐Ÿ“",
    })

    // Mocks should be added in the same order their calls are made.
    // However, this order will only be enforced on calls to the same endpoint
    // using the same http method.
    m.SendText(discord.Message{
        ChannelID: channelID,
        Content: "Pong!"
    })

    b := NewBot(s)

    b.Ping(&gateway.MessageCreateEvent{
        Message: discord.Message{ChannelID: channelID}
    })
}
Advanced Testing

Now imagine a bit more complicated test, that has multiple sub-tests:

func (b *Bot) Ping(e *gateway.MessageCreateEvent) (error) {
    _, err := b.Ctx.SendText(e.ChannelID, "๐Ÿ“")
    if err != nil {
        return err
    }

    _, err := b.Ctx.SendText(e.ChannelID, e.Author.Mention()+" Pong!")
    
    return err
}
func TestBot_Ping(t *testing.T) {
    m := dismock.New(t)
    // no need to call m.Eval() as we'll only use the mocker for cloning anyway

    var channelID discord.ChannelID = 123

    m.SendText(discord.Message{
        ChannelID: channelID,
        Content: "๐Ÿ“",
    })
    
    t.Run("test1", func(t *testing.T) {
        // If you have multiple tests that make the same requests, you can
        // create a mocker, and add those API calls.
        // Afterwards, you can create a clone of the mocker in every sub-test 
        // you have.
        // Cloned mockers have a copy of their parent's request, but run their
        // own mock server and have a dedicated Session/State.
        m, s := m.CloneState(t)
        defer m.Eval()

        ...
    })

    t.Run("test2", func(t *testing.T) {
        m, s := m.CloneState(t)
        defer m.Eval()
        
        ...
    })
}
Using a Different Discord Library

Since mocking is done on a network level, you are free to chose whatever discord library you want. Simply use dismock.New when creating a mocker, replace the http.Client of your library of choice with mocker.Client, and disable the state.

Below is an example of using dismock with discordgo.

m := dismock.New(t)

s, _ := discordgo.New("Bot abc") // the token doesn't have to be valid
s.StateEnabled = false
s.Client = m.Client
Meta Requests

Besides regular calls to the API, you can also mock requests for metadata, i.e. images such as guild icons (Mocker.GuildIcon). In order for this to work you need to use the http.Client found in the Mocker struct, so that the mock server will be called instead of Discord.

Directories ยถ

Path Synopsis
internal
pkg
dismock
Package dismock creates mocks for the Discord API.
Package dismock creates mocks for the Discord API.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL