所以目前我有一个http处理程序,如下所示:
type App struct {
}
func (a *App) someHandler(w http.ResponseWriter, r *http.Request) {
var api = slack.New("TOKEN")
users = api.GetUsers()
}
我想为此slack.New(“ ...”)调用创建一个接口,以便在我的测试中api不会发出网络请求以使其松弛。
如何模拟此新通话?
调用New(“ TOKEN”)返回一个* Client,请参见下面的链接:
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
我还没有使用过接口,所以不确定是否不能将其放在接口中,因为对New的调用就像构造函数一样?
答案 0 :(得分:2)
您无法模拟slack.New
调用本身,而是必须创建一个行为类似于此api
对象的模拟。为此,将api
放在App
结构上,但要作为一个接口:
type SlackClient interface {
GetUsers() []string
}
type App struct {
api SlackClient
}
func (a *App) someHandler(w http.ResponseWriter, r *http.Request) {
users = a.api.GetUsers()
}
然后,您必须将对slack.New
的调用移到构成App
的任何结构中(例如您的主函数或NewApp
构造函数):
app = App{api: slack.New("TOKEN")}
返回的* Client上有一个GetUsers
方法,因此将匹配我们定义的接口。
然后,该测试通过模拟执行类似的操作:
type mockSlackClient struct {
}
func (m *mockSlackClient) GetUsers() []string {
return nil
}
func TestSomeHandler(t *testing.T) {
appToTest := App{api: &mockSlackClient{})
appToTest.someHandler(httptest.NewRecorder(), nil)
}
同样,由于*mockSlackClient
上具有GetUsers
方法,它将满足该接口,因此您将能够在App
上使用它。