所以目前我有一个看起来像这样的 http 处理程序:
type App struct {
}
func (a *App) someHandler(w http.ResponseWriter, r *http.Request) {
var api = slack.New("TOKEN")
users = api.GetUsers()
}
我想为这个 slack.New("...") 调用创建一个接口(interface),这样在我的测试中 api 就不会向 slack 发出网络请求。
我如何模拟这个新调用?
调用 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
我没有经常使用接口(interface),所以不确定是否不能将其放入接口(interface)中,因为对 New 的调用就像一个构造函数?
最佳答案
您不能模拟 slack.New
调用本身,而是必须创建一个行为类似于此 api
对象的模拟。为此,将 api
作为接口(interface)放在 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
方法,因此将匹配我们定义的接口(interface)。
然后测试用模拟做一些类似的事情:
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
方法,它将满足接口(interface),因此您将能够在 App
上使用它>.
关于go - 我怎样才能将这个 api 提取到一个接口(interface),以便我可以在我的测试中模拟它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53126695/