为了账号安全,请及时绑定邮箱和手机立即绑定

在 GO 语言中模拟

在 GO 语言中模拟

Go
PIPIONE 2022-05-23 17:20:40
我是Go新手,我仍在努力理解它的概念。我正在尝试创建一个简单的单元测试并想要Mock它的一项服务。我想模拟my_mod_2.EmpInfo它,这样我就不会调用实际的服务。方法1.gopackage my_mod_1import (    "awesomeProject-1/my-mod-2")func CreateAndSendMail() string {    svc := my_mod_2.EmpInfo{}    name := svc.GetName()    empAddress := svc.GetAddress()    return name + " lives in " + empAddress}这里是Emp.gopackage my_mod_2import "fmt"type EmpInfo struct {}func (o EmpInfo) GetName()  string{    fmt.Println("Called actual")    return "John Doe"}func (o EmpInfo) GetAddress() string {    return "US"}这是method-1_test.gopackage my_mod_1import (    "testing")func TestCreateAndSendMail(t *testing.T) {    val := CreateAndSendMail()    if val != "John Doe lives in US" {        t.Error("Value not matched")    }}我Called actual在测试执行中看到。我知道我必须使用创建一个模拟,interface但我就是不明白。有人可以帮我解决这个小代码吗?
查看完整描述

2 回答

?
慕尼黑5688855

TA贡献1848条经验 获得超2个赞

首先,您需要准备代码以使用接口和模拟。为此,我建议您在方法Service旁边声明接口CreateAndSendMail。在这种情况下,最好将服务实例传递给方法或将其用作方法所属结构的实例变量:


type Service interface {

    GetName() string

    GetAddress() string

}


func CreateAndSendMail(svc Service) string {

    name := svc.GetName()

    empAddress := svc.GetAddress()

    return name + " lives in " + empAddress

}

或者


type Service interface {

    GetName() string

    GetAddress() string

}


type S struct {

    svc Service

}


func (s *S) CreateAndSendMail() string {

    name := s.svc.GetName()

    empAddress := s.svc.GetAddress()

    return name + " lives in " + empAddress

}

然后,您将隐式EmpInfo实现您的接口。Service这是 golang 接口的一个很酷的特性。在我们所有的准备工作之后,我们准备创建测试。为此,我们可以自己实现模拟:


import (

    "testing"

)


type MockSvc struct {

}


func (s *MockSvc) GetName() string {

    return "Mocked name"

}


func (s *MockSvc) GetAddress() string {

    return "Mocked address"

}


func TestCreateAndSendMail(t *testing.T) {

    svc := &MockSvc{}


    val := CreateAndSendMail(svc)

    if val != "Mocked name lives in Mocked address" {

        t.Error("Value not matched")

    }

}


此外,我们可以使用特殊工具gomock来自动化模拟创建过程


查看完整回答
反对 回复 2022-05-23
?
阿晨1998

TA贡献2037条经验 获得超6个赞

接口是帮助测试的最常用的 Go 特性。Go 中的接口允许 Duck Typing,您可以在其中切换已实现接口的任何类型以被不同类型模拟。


从您的示例中,该服务具有以下两种方法:GetName() 和 GetAddress()。用这两种方法创建一个接口Service。


type Service Interface {

    GetName() string

    GetAddress() string

}

现在您的 struct EmpInfo 已经实现了 Service 接口。使用相同的 2 个函数创建一个新的 MockService 结构。


type MockService struct {}


func (ms *MockService) GetName() string {

// Mock Code

}


func (ms *MockService) GetAddress() string {

// Mock Code

}

然后,在需要的地方用 MockService 替换 EmpInfo 的实例。


PS:考虑使用指向 EmpInfo 的指针添加函数 GetName 和 GetAddress。


查看完整回答
反对 回复 2022-05-23
  • 2 回答
  • 0 关注
  • 133 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信