slack-go / slack

Slack API in Go, originally by @nlopes; Maintainers needed, contact @parsley42
https://pkg.go.dev/github.com/slack-go/slack
BSD 2-Clause "Simplified" License
4.63k stars 1.12k forks source link

Expose the "Binder" type in slacktest #1176

Closed kpaulisse closed 1 year ago

kpaulisse commented 1 year ago

Description

TL;DR: Please change binder to Binder in slacktest/server.go.

The binder type is defined as such in slacktest/server.go:

type binder func(Customize)

This is only used in the signature of func NewTestServer(custom ...binder) *Server.

Due to the order of initialization of the handlers, once a handler is initialized, calling the Handler method again will be ignored. The NewTestServer function initializes a bunch of handlers.

In one of our tests, we wanted to redefine /conversations.info and some others, and the only way we could do so was to supply them like so:

s := slacktest.NewTestServer(
  func(c slacktest.Customize) {
    c.Handle("/chat.postEphemeral", chatPostEphemeralHandler(...))
  },
  func(c slacktest.Customize) {
    c.Handle("/conversations.info", conversationsInfoHandler(...))
  },
  func(c slacktest.Customize) {
    c.Handle("/chat.postMessage", chatPostMessageHandler(...))
  },
)

However this is not amenable to table-driven tests. We'd like to be able to create our own []slacktest.Binder and pass these to slacktest.NewTestServer running in a subtest.

t.Run(testcase.Name, func(t *testing.T) {
  s := slacktest.NewTestServer(testcase.CustomFuncs...)
  // ...
}

However, because binder is private, there is no way to do this.

With Binder exported we can create []slacktest.Binder as an entry in each row of our table-driven tests and then pass this slice to NewTestServer as we would prefer.