gpt4 book ai didi

go - golang 中的依赖注入(inject)

转载 作者:数据小太阳 更新时间:2023-10-29 03:20:50 35 4
gpt4 key购买 nike

我有以前的代码,其工作方式如下:

  1. call to function getData which provide you data to execute the http request
  2. use the getData function output to execute the http request.

这以前是可行的,但现在我想为它做单元测试,我读了一些博客如何让它工作,似乎依赖注入(inject)是实现它的关键。我试着关注 this post .

我尝试采用该代码,但不确定我是否做对了。

想法是在产品中使用 getData 函数和一些要执行的 url,并在 unit test 中提供不同的 url,例如 httptest.NewServer(testHandler) 我应该如何在 Go 中使其正确?

package main

import (
"fmt"
"io/ioutil"
"net/http"
)

type requester interface {
HTTPRequest(c string, i string, mtd string, url string) (p []byte, e error)
}
func (i impl) HTTPRequest(c string, ci string, mtd string, url string) (p []byte, e error) {
req, err := http.NewRequest(mtd, url, nil)
if err != nil {
return nil, err
}
req.SetBasicAuth(c, ci)
res, err := i.client.Do(req)
if err != nil {
return nil, err
}
token, err := ioutil.ReadAll(res.Body)
if err != nil {
return nil, err
}
defer res.Body.Close()
fmt.Println("success")
return token, nil
}

type iData interface {
getData() []string
}

type reqData struct {
f1 string
f2 string
}

func (s reqData) getData() []string {
a := make([]string, 4)
a[2] = "http://www.mocky.io/v2/5c20eccc2e00005c001e0c84"
a[3] = "/oauth/token?grant_type=client_credentials"
return a
}

type ServiceInfo struct {
req requester
data iData
}

type impl struct {
client *http.Client
}

func NewServiceInfo(http requester, data iData) *ServiceInfo {
return &ServiceInfo{
req: http,
data: data,
}
}

// ----This is the function which I need to mock
func (s *ServiceInfo) caller() {
// Function 1 - get the values
reqdata := s.data.getData()
// Function 2 -call to http function
s.req.HTTPRequest(reqdata[0], reqdata[1], "POST", reqdata[2])
}

func main() {
// not sure how to run it
//httpClient := http.Client{}
//d := reqData{f1: "user", f2: "password"}

//s := NewServiceInfo(impl{client: &httpClient}, d.getData())
//s.caller()
}

测试看起来像这样,但真的不确定如何让它工作

    It("Test", func() {

// Mock http call
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
u, p, ok := r.BasicAuth()
Ω(ok).Should(Equal(true))
Ω(u).Should(Equal("user"))
Ω(p).Should(Equal("password"))
}))

var httpClient = http.Client{}
si := NewServiceInfo(client{httpClient: &httpClient, url: server.URL})
t, err := si.r.httpReq("user", "password", http.MethodPost)

Ω(token).Should(Equal(string(t)))
Ω(err).ShouldNot(HaveOccurred())

})

该代码只是我完整代码的示例,所以我尝试使用它并只放置相关部分

更新让它更清楚:)

我需要的是如何模拟(正确的方式)函数 getData ,在产品代码中提供 url x 并在测试中提供 url y,这里的细微差别是我需要对函数 caller 进行单元测试

让它工作这不是问题,但这里的问题是让它成为可测试的代码

https://play.golang.org/p/UQqtZmNS5BK

最佳答案

我一直在使用 https://github.com/facebookgo/inject对于 DI 和 https://github.com/golang/mock mock 。例如:

// some_entity_dao.go
type SomeEntity interface {
Find(ctx context.Context, condition *model.SomeEntity) (*model.SomeEntity, error)
FindAll(ctx context.Context, condition *model.SomeEntity) ([]*model.SomeEntity, error)
Save(ctx context.Context, data *model.SomeEntity) error
Update(ctx context.Context, condition *model.SomeEntity, data *model.SomeEntity) error
Delete(ctx context.Context, condition *model.SomeEntity) error
}

并使用以下方法生成模拟实现:

//go:generate mockgen -source=./some_entity_dao.go -destination=./some_entity_dao_mock_impl.go -package dao

然后在编写单元测试时使用这个模拟实现。

关于go - golang 中的依赖注入(inject),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54262128/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com