go - 如何将此 api 提取到接口,以便在测试中模拟它?
问题描述
所以目前我有一个 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 不会向 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
我没有太多使用接口,所以不确定是否不能将其放入接口中,因为对 New 的调用就像一个构造函数?
解决方案
您不能模拟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
.
推荐阅读
- python - 列值四舍五入的问题
- javascript - 如何修复 React 中页面加载时的 FontAwesome 图标很大
- amazon-web-services - 无法通过 AWS SDK 确认用户注册
- jenkins - 使用 Jenkins 部署到 ec2 实例的步骤
- php - 在 laravel 和 Visual Studio 代码中是否有解决我的问题的方法
- javascript - 序列化 Laravel 刀片阵列
- amazon-web-services - 带有 MD5 哈希的“密码必须包含大写的 ASCII 字符”
- python - 使用 Python 和 Flask 的待办事项列表,无法在我的“已完成任务页面”上反映任务
- npm - run npm script after package installing
- go - 高等待时间在获得响应或上下文截止日期之前超出 go-micro