我有这个功能,我需要在测试中模拟,我能够按照HTTP模拟软件包按预期进行模拟,但是现在我正在调用的功能到HttpReq
方法,在这里我无法使用HTTP模拟软件包我读了有关依赖注射的信息,但尝试了一些东西,但我无法完全做到这一点,
这是功能
type params struct {
cs string
ci string
method string
url string
}
// I added this struct but not sure if it's needed ... probably for test purpose but not sure how to use it.
type Impl struct {
client *http.Client
}
func (i *Impl) HttpReq(p *params) ([]byte, error) {
httpClient := i.client
req, err := http.NewRequest(p.method, p.url, nil)
if err != nil {
fmt.Sprintf(err)
}
req.SetBasicAuth(p.cs, p.ci)
res, err := httpClient.Do(req)
if err != nil {
fmt.Sprintf(err)
}
t, err := ioutil.ReadAll(res.Body)
if err != nil {
fmt.Sprintf(err)
}
defer res.Body.Close()
return t, nil
}
这就是我尝试的
我已经创建了接口
type Req interface {
HttpReq(params) ([]byte, error)
}
现在我创建了一个包含接口的结构
type Service struct {
req Req
}
这是我需要测试的功能
func (c *Service) execute(cli Connection , args []string) (error, []byte) {
sk, err := c.doSomthing(cli, args)
sc, err := c.doSometing2(serviceK, []string{"url", "cl", "ct"})
cc := strings.Fields(serviceCredentials)
// ----------Here is what I need to mock ----------
t, err := c.req.HttpReq(params{cs: cc[1],
ci: cc[2],
method: http.MethodPost,
url: cc[0],})
return err, t
}
任何想法我如何运行此功能测试???我很挣扎很多。
独立于原始问题,您不应为每个请求创建新的HTTP客户端。客户的维护池,应尽可能重复使用。
您可以解决此问题,并通过注入HTTP客户端继续使用现有的模拟服务器。
还请注意,问题中的接口定义与实现不符。这两个方法签名不是相同的:
HttpReq(params) ([]byte, error) // Req
HttpReq(*params) ([]byte, error) // Impl
选择一个。我可能会在此处使用非分子类型。大写字母缩写为GO(HTTPReq
,而不是HttpReq
)。
将客户端添加到Impl
类型中,然后在HTTPReq
中使用它:
type Impl struct {
client *http.Client
}
func (i *Impl) HTTPReq(p params) ([]byte, error) {
req, err := http.NewRequest(p.method, p.url, nil)
if err != nil {
return nil, err
}
req.SetBasicAuth(p.cs, p.ci)
res, err := i.client.Do(req)
if err != nil {
return nil, err
}
defer res.Body.Close()
return ioutil.ReadAll(res.Body)
}
服务类型不必更改。
在测试中,只需将测试客户端注入Impl
值:
import (
"context"
"net"
"net/http"
"net/http/httptest"
"testing"
)
func TestService_execute(t *testing.T) {
var testHandler http.Handler // TODO
srv := httptest.NewServer(testHandler)
defer srv.Close()
client := srv.Client()
tp := client.Transport.(*http.Transport)
// Direct all requests to the test server, no matter what the request URL is.
tp.DialContext = func(ctx context.Context, network, addr string) (net.Conn, error) {
// Note that we ignore the network and addr parameters, since these are
// derived from the request URL and are unrelated to the test server.
srvAddr := srv.Listener.Addr()
return (&net.Dialer{}).DialContext(ctx, srvAddr.Network(), srvAddr.String())
}
svc := &Service{
req: &Impl{
client: client,
},
}
svc.execute(/* ... */)
// assert request, response, etc.
}
由于服务结构已经具有REQ接口,在测试以满足REQ接口的模拟测试初始服务对象期间。像这样的东西
https://stackoverflow.com/a/53805535/3968921