Go语言 如何为自定义HTTP客户端设置接口?

0vvn1miw  于 2022-12-07  发布在  Go
关注(0)|答案(2)|浏览(135)

我在为我导入的第三方库编写测试时遇到了困难。我想这是因为我希望我的CustomClient结构体有一个client接口而不是*banker.Client。这使得测试非常困难,因为很难模拟*banker.Client。有什么想法可以正确地将其转换为接口吗?这样我就可以很容易地编写模拟测试并建立一个假客户端?

type CustomClient struct {
    client     *banker.Client //I want to change this to an interface
    name  string
    address string
}

func (c *CustomClient) SetHttpClient(httpClient *banker.Client) { //I want to accept an interface so I can easily mock this.
    c.client = httpClient
}

问题是banker.Client是我导入的第三方客户端,其中包含许多结构体和其他字段。它看起来像这样:

type Client struct {
    *restclient.Client
    Monitor    *Monitors
    Pricing    *Pricing
    Verifications *Verifications
}

最终结果是我的代码看起来像这样:

func (c *CustomClient) RequestMoney() {
    _, err := v.client.Verifications.GetMoney("fakeIDhere")

}
zzlelutf

zzlelutf1#

如果方法覆盖结构体上的字段,这肯定不是一个简单的解决方案。然而,我们可以尝试最小化当前包上的冗长测试用例。
在你的工作包和银行家之间再加一层(包)。简化例子中的代码来解释。
假设您的banker包包含以下代码:

type Client struct {
    Verification *Verification
}

type Verification struct{}

func (v Verification) GetMoney(s string) (int, error) {
    ...
}

创建另一个导入banker并定义了接口的包,例如bankops包:

type Bank struct {
    BankClient *banker.Client
}

type Manager interface {
    GetMoney(s string) (int, error)
}

func (b *Bank) GetMoney(s string) (int, error) {
    return b.BankClient.Verification.GetMoney(s)
}

注意:实际的问题(没有接口的测试)仍然在bankops包中,但这更容易测试,因为我们只是转发结果。用于单元测试。
最后,在当前的包(对我来说,它是main包)中,我们可以

type CustomClient struct {
    client bankops.Manager
}

func (c *CustomClient) RequestMoney() {
    _, err := c.client.GetMoney("fakeIDhere")
    ...
}

func main() {
    client := &CustomClient{
        client: &bankops.Bank{
            BankClient: &banker.Client{
                Verification: &banker.Verification{},
            },
        },
    }

    client.RequestMoney()
}

有关工作示例,请签入Playground
您可以像在原始代码片段中那样添加settersbuilders pattern,以使字段(如BankerClient)不导出。

t9eec4r0

t9eec4r02#

我认为不可能直接把它做成接口,因为我们应该使用Client的成员变量。
把它的成员做成接口怎么样?比如,

for _, test := []struct{}{
      testVerification VerificationInterface
   }{{
      testVerification: v.Client.Verifications
   },{
      testVerification: VerficationMock
   }}{
      // test code here
   }

相关问题