为什么我们使用接口作为模拟方法Golang

问题描述

我是Golang的新手,一直在探索,但不清楚单元测试中的模拟。任何人都可以解释以下特定问题吗?

Question1 :为了用Golang编写单元测试,为什么我们需要接口来模拟方法,为什么不仅要使用struct?

问题2 :为什么我们将接口注入struct(我们称之为外部方法)

使用结构-

type GlobalData struct {}

var (
    GlobalObj = GlobalData{}
)

func (g GlobalData) GetGlobalData(a string) string{
    return a
}

具有接口定义-

type GlobalInterface interface {
    GetGlobalData(a string) string
}

type GlobalData struct {}

var (
    GlobalObj = GlobalData{}
)

func (g GlobalData) GetGlobalData(a string) string{
    return a
}

谢谢

解决方法

问题1 :为了在Golang中编写单元测试,为什么我们需要接口来模拟方法,为什么不仅要使用struct?

答案:它不是强制性的

问题2 :为什么我们将接口注入struct(我们称之为外部方法)

答案:因为,它可以帮助您替换实际的函数调用(这可能会触发一些超出范围的操作,作为单元测试的一部分,例如数据库调用某些API调用) 等),方法是注入MockStruct(将实现与实际代码中相同的interface)。 多态,简而言之。

因此,您创建一个MockStruct并为其定义自己的mockMethods。作为多态,您的单元测试选择MockStruct不会抱怨。呼叫实际的数据库端点或http端点不属于单元测试

仅供参考,我可以将您指向我的github代码库之一,其中我为small test case编写了a file。如您所见,我很嘲笑:

  1. GuestCartHandler interface,这使我无法打电话给actual implementation
  2. 使用"github.com/DATA-DOG/go-sqlmock"软件包模拟sql connection。这有助于我避免建立实际的db client(因此,在进行单元测试时不依赖数据库)

请让我知道您是从概念上获得创意还是需要进一步澄清。

,

如果您在包用户中有关于类型的方法,比如说。 套餐用户

 selected_fields = ['Player bio','team']

现在在目录包中导入:

type User struct {
 name string
}

func (u *User) GetUserProfile() UserProfile{}

现在要测试getUserCatalog方法有两种方法:

package catalog

import user

func getUserCatalog(user user.User) []catalog {
 user.GetUserProfile()
}

使用这种方法可以在测试运行时轻松通过模拟,例如:

1. var getUserProfileFunc = user.GetUserProfile

这是测试它的最简单方法。

现在有另一种使用界面的方式,在包用户中添加类似的界面

getUserProfile = func() UserProfile { 
 return fakeUserProfile 
}

如果用户包是您无法控制的库,则创建您自己的界面,键入并使用它。

在这种情况下,目录包中的测试将变为:

因为现在将从UserInterface类型而不是从UserType调用方法,因此在测试时:

type UserInterface interface {
  GetUserProfile() UserProfile
}

并按照以下步骤操作

UserInterface = fakeUserStruct

现在运行测试时:

//1. define type of func to return 

type typeGetUserProfile func() UserProfile

//2. create a var to return

var mockedGetUserProfile typeGetUserProfile

//3. create a type

type FakeUser struct{}

//4. implement method interface

func (user *FakeUserStruct) GetUserProfile() UserProfile{
  return mockedGetUserProfile
 }

有一个模拟库,可以帮助创建用于模拟的样板代码。选中此https://github.com/stretchr/testify

还有许多其他的模拟库,但是我使用过这个库,真的很棒。

我希望这会有所帮助。

如果不能,请告诉我,我将给出一些示例代码并将其推送到Github。

也请检查https://levelup.gitconnected.com/utilizing-the-power-of-interfaces-when-mocking-and-testing-external-apis-in-golang-1178b0db5a32

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...