模拟结构字段的方法
Mocking a struct field's methods
我正在开发一个执行 OAuth 身份验证的简单 golang 服务器应用程序。服务器代码很简单。对于单元测试,我需要避免向实际的 OAuth 提供程序发出外部 HTTP 请求。
所以在正常的Server操作中,我想使用真正的调用,而当运行 go test
,使用Mock方法来阻止外部HTTP请求。
我已经创建了 OAuth 方法的模拟,但我不了解如何将它们集成到代码中的机制。看了 mock 的例子,mock 接口是怎么用的,我还是一头雾水。
原代码如下:
type Server struct {
//This is the actual golang.org/x/oauth2 Config struct
oauth2Config *oauth2.Config
}
func (s *Server) handleCallback() http.HandlerFunc {
// This is the method that makes external call. I want to mock it
oauth2Token, err := s.oauth2Config.Exchange(s.context, r.URL.Query().Get("code"))
}
我定义了一个接口,mock函数
type Oauth2ConfigInterface interface {
Exchange(ctx context.Context, code string, opts ...oauth2.AuthCodeOption) (*oauth2.Token, error)
}
type MockOauth2Config struct {
}
func (o *MockOauth2Config) Exchange(ctx context.Context, code string, opts ...oauth2.AuthCodeOption) (*oauth2.Token, error) {
return &oauth2.Token{}, nil
}
我本以为我应该更改原始服务器结构以使用新接口:
- 在正常的服务器操作中,oauth2Config 字段分配有 &oath2.Config{}
- 在测试中,oauth2Config 字段被分配了 &MockOauth2Config{}
type Server struct {
//Changed to interface
oauth2Config Oauth2ConfigInterface
}
...
oauth2Config: &oauth2.Config{
ClientID: "",
ClientSecret: "",
RedirectURL: "",
Scopes: []string{oidc.ScopeOpenID},
},
但是当我尝试访问 oauth2Config 的字段时,出现编译错误。
// compile error here
s.verifier = s.provider.Verifier(&oidc.Config{ClientID: s.oauth2Config.ClientID})
一旦 oauth2Config 被声明为接口,我该如何访问这些字段?
还是我做错了整个模拟?
回答我自己的问题...
我的问题可能措辞不当,但我确实认为未来的人 运行 会遇到同样的问题。
@bcmills 给出了最好的解决方案:
它比使用接口模拟要优雅得多。尤其是像这种涉及第三方func/methods的情况。
我正在开发一个执行 OAuth 身份验证的简单 golang 服务器应用程序。服务器代码很简单。对于单元测试,我需要避免向实际的 OAuth 提供程序发出外部 HTTP 请求。
所以在正常的Server操作中,我想使用真正的调用,而当运行 go test
,使用Mock方法来阻止外部HTTP请求。
我已经创建了 OAuth 方法的模拟,但我不了解如何将它们集成到代码中的机制。看了 mock 的例子,mock 接口是怎么用的,我还是一头雾水。
原代码如下:
type Server struct {
//This is the actual golang.org/x/oauth2 Config struct
oauth2Config *oauth2.Config
}
func (s *Server) handleCallback() http.HandlerFunc {
// This is the method that makes external call. I want to mock it
oauth2Token, err := s.oauth2Config.Exchange(s.context, r.URL.Query().Get("code"))
}
我定义了一个接口,mock函数
type Oauth2ConfigInterface interface {
Exchange(ctx context.Context, code string, opts ...oauth2.AuthCodeOption) (*oauth2.Token, error)
}
type MockOauth2Config struct {
}
func (o *MockOauth2Config) Exchange(ctx context.Context, code string, opts ...oauth2.AuthCodeOption) (*oauth2.Token, error) {
return &oauth2.Token{}, nil
}
我本以为我应该更改原始服务器结构以使用新接口:
- 在正常的服务器操作中,oauth2Config 字段分配有 &oath2.Config{}
- 在测试中,oauth2Config 字段被分配了 &MockOauth2Config{}
type Server struct {
//Changed to interface
oauth2Config Oauth2ConfigInterface
}
...
oauth2Config: &oauth2.Config{
ClientID: "",
ClientSecret: "",
RedirectURL: "",
Scopes: []string{oidc.ScopeOpenID},
},
但是当我尝试访问 oauth2Config 的字段时,出现编译错误。
// compile error here
s.verifier = s.provider.Verifier(&oidc.Config{ClientID: s.oauth2Config.ClientID})
一旦 oauth2Config 被声明为接口,我该如何访问这些字段?
还是我做错了整个模拟?
回答我自己的问题...
我的问题可能措辞不当,但我确实认为未来的人 运行 会遇到同样的问题。
@bcmills 给出了最好的解决方案:
它比使用接口模拟要优雅得多。尤其是像这种涉及第三方func/methods的情况。