douduikai0562 2018-11-02 22:47
浏览 10
已采纳

如何将这个api提取到接口,以便可以在测试中模拟它?

So currently I have a http handler that looks like:

type App struct {

}
func (a *App) someHandler(w http.ResponseWriter, r *http.Request) {
        var api = slack.New("TOKEN")
        users = api.GetUsers()
}

I want to create an interface for this slack.New("...") call so that in my tests the api doesn't make network requests to slack.

How can I mock this New call?

The call New("TOKEN") returns a *Client, see the link below:

func New(token string, options ...Option) *Client {
    s := &Client{
        token:      token,
        httpclient: &http.Client{},
        log:        log.New(os.Stderr, "nlopes/slack", log.LstdFlags|log.Lshortfile),
    }

    for _, opt := range options {
        opt(s)
    }

    return s
}

https://github.com/nlopes/slack/blob/0f8db5050731c50359e319cf253af5b9997a2b1e/slack.go#L84

I haven't used interfaces that much so not sure if this can't be put in a interface since the call to New is like a constructor?

  • 写回答

1条回答 默认 最新

  • dongxing9219 2018-11-03 06:40
    关注

    You can't mock the slack.New call itself, instead you have to create a mock that behaves like this api object. To do this put the api onto the App struct but as an interface:

    type SlackClient interface {
        GetUsers() []string
    }
    
    type App struct {
        api SlackClient
    }
    
    func (a *App) someHandler(w http.ResponseWriter, r *http.Request) { 
        users = a.api.GetUsers() 
    }
    

    You then have to move the call to slack.New into whatever constructs the App (for instance your main function or a NewApp constructor function):

    app = App{api: slack.New("TOKEN")}
    

    The *Client this returns has a GetUsers method on it so will match the interface we have defined.

    The test then does something similar with a mock:

    type mockSlackClient struct {
    
    }
    
    func (m *mockSlackClient) GetUsers() []string {
        return nil
    }
    
    func TestSomeHandler(t *testing.T) {
        appToTest := App{api: &mockSlackClient{})
    
        appToTest.someHandler(httptest.NewRecorder(), nil)
    }
    

    Again as the *mockSlackClient has a GetUsers method on it it will satisfy the interface so you will be able to use it on the App.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 Centos7 / PETGEM
  • ¥15 csmar数据进行spss描述性统计分析
  • ¥15 各位请问平行检验趋势图这样要怎么调整?说标准差差异太大了
  • ¥15 delphi webbrowser组件网页下拉菜单自动选择问题
  • ¥15 wpf界面一直接收PLC给过来的信号,导致UI界面操作起来会卡顿
  • ¥15 init i2c:2 freq:100000[MAIXPY]: find ov2640[MAIXPY]: find ov sensor是main文件哪里有问题吗
  • ¥15 运动想象脑电信号数据集.vhdr
  • ¥15 三因素重复测量数据R语句编写,不存在交互作用
  • ¥15 微信会员卡等级和折扣规则
  • ¥15 微信公众平台自制会员卡可以通过收款码收款码收款进行自动积分吗