title: How to compare/match closures in mocks?
body: <p>TL;DR: mocked method accepts closure. I wonder how to create custom matcher (<a href="https://godoc.org/github.com/golang/mock/gomock#Matcher" rel="nofollow noreferrer">https://godoc.org/github.com/golang/mock/gomock#Matcher</a>): closure itself in turn is working with private structure - meaning I can't even call the closure in my test to check it against expectations.</p>
  
  <hr>
  
  <p>I'm working on a small app using Slack API with help of nlopes/slack (<a href="https://github.com/nlopes/slack" rel="nofollow noreferrer">https://github.com/nlopes/slack</a>).</p>
  
  <p>For testing, I'm mocking nlopes/slack with gomock. For that I've created interface</p>
  
  <pre><code>type slackAPI interface {
      OpenConversation(*slack.OpenConversationParameters) (*slack.Channel, bool, bool, error)
      PostMessage(channelID string, options ...slack.MsgOption) (string, string, error)
      GetUserByEmail(email string) (*slack.User, error)
  }
  </code></pre>
  
  <p>I have no problem testing OpenConversation or GetUserByEmail, e.g.</p>
  
  <pre><code>slackAPIClient.
      EXPECT().
      GetUserByEmail("some@email.com").
      Return(slackUserJohndoe, nil).
      Times(1)
  </code></pre>
  
  <p>Things get more complicated when it comes to PostMessage. In main code the call looks like</p>
  
  <pre><code>_, _, err := slackAPIClient.PostMessage(channel.ID, slack.MsgOptionText(message, false))
  </code></pre>
  
  <p>And slack.MsgOptionText (from nlopes/slack) is actually returning closure:</p>
  
  <pre><code>func MsgOptionText(text string, escape bool) MsgOption {
      return func(config *sendConfig) error {
          if escape {
              text = slackutilsx.EscapeMessage(text)
          }
          config.values.Add("text", text)
          return nil
      }
  }
  </code></pre>
  
  <p>Since method is accepting closure, I need to create custom gomock matcher (<a href="https://godoc.org/github.com/golang/mock/gomock#Matcher" rel="nofollow noreferrer">https://godoc.org/github.com/golang/mock/gomock#Matcher</a>). Custom matcher itself is not a problem, it would look something like</p>
  
  <pre><code>type higherOrderFunctionEqMatcher struct {
      x interface{}
  }
  
  func (e hofEqMatcher) Matches(x interface{}) bool {
      //return m.x == x
      return true
  }
  
  func (e hofEqMatcher) String(x interface{}) string {
      return fmt.Sprintf("is equal %v", e.x)
  }
  </code></pre>
  
  <p>However, since MsgOptionText uses nlopes/slack private structure sendConfig, I wonder how can I even work with that in scope of my test to check equality to expectations.</p>
  
  <p>How should I tackle such problem?</p>