为了账号安全,请及时绑定邮箱和手机立即绑定

如何比较/匹配模拟中的闭包?

如何比较/匹配模拟中的闭包?

Go
炎炎设计 2022-05-18 15:55:58
模拟方法接受闭包。我想知道如何创建自定义匹配器(https://godoc.org/github.com/golang/mock/gomock#Matcher):闭包本身又使用私有结构 - 这意味着我什至不能在我的测试以检查它是否符合预期。我正在 nlopes/slack ( https://github.com/nlopes/slack ) 的帮助下使用 Slack API 开发一个小型应用程序。为了测试,我用 gomock 模拟 nlopes/slack。为此,我创建了界面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)}我在测试 OpenConversation 或 GetUserByEmail 时没有问题,例如slackAPIClient.    EXPECT().    GetUserByEmail("some@email.com").    Return(slackUserJohndoe, nil).    Times(1)当涉及到 PostMessage 时,事情变得更加复杂。在主代码中,调用看起来像_, _, err := slackAPIClient.PostMessage(channel.ID, slack.MsgOptionText(message, false))而 slack.MsgOptionText (来自 nlopes/slack)实际上正在返回闭包: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    }}由于方法接受关闭,我需要创建自定义 gomock 匹配器(https://godoc.org/github.com/golang/mock/gomock#Matcher)。自定义匹配器本身不是问题,它看起来像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)}但是,由于 MsgOptionText 使用 nlopes/slack 私有结构 sendConfig,我想知道如何在我的测试范围内使用它来检查与预期的相等性。我应该如何解决这样的问题?
查看完整描述

1 回答

?
斯蒂芬大帝

TA贡献1827条经验 获得超8个赞

牢记这一点

  1. 在 Golang 你不能比较函数

  2. 在这种精确的情况下,我不能通过调用闭包本身来进行间接测试(因为它使用私有 3rd 方库的结构作为参数)

我找到的解决方案是模拟 slack.MsgOptionText(message, false),然后返回 PostMessage(channelID string, options ...slack.MsgOption) 的闭包:


type slackMsgCreator interface {

    MsgOptionText(string, bool) slack.MsgOption

}


type slackMsgCreatorInst struct{}


func (s slackMsgCreatorInst) MsgOptionText(text string, escape bool) slack.MsgOption {

    return slack.MsgOptionText(text, escape)

}

...


slackMsgCreator.

    EXPECT().

    MsgOptionText("Dear John Doe, message goes here", false).

    Return(slack.MsgOptionText("Dear John Doe, message goes here", false)).

    Times(1)

而且,至于 PostMessage - 正如评论中所建议的那样,我唯一可以检查的是闭包不是零:


slackAPIClient.

    EXPECT().

    PostMessage("ABCDE", Not(Nil())).

    AnyTimes()


查看完整回答
反对 回复 2022-05-18
  • 1 回答
  • 0 关注
  • 107 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号