我是 的新手前往 我仍在努力理解它的概念。我正在尝试创建一个简单的单元测试并希望 Mock
它的服务之一。我想模拟my_mod_2.EmpInfo
在其中,这样我就不会调用实际的服务。
方法1.go
package my_mod_1
import (
"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.go
package my_mod_2
import "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.go
package my_mod_1
import (
"testing"
)
func TestCreateAndSendMail(t *testing.T) {
val := CreateAndSendMail()
if val != "John Doe lives in US" {
t.Error("Value not matched")
}
}
我看到
Called actual
在测试执行中。我知道我必须使用 interface
创建一个模拟但我就是不明白。有人可以帮我解决这个小代码吗?
最佳答案
首先,您需要准备代码以使用接口(interface)和模拟。为此,我建议您声明 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
隐式接口(interface)。这是 golang 接口(interface)的一个很酷的特性。在我们所有的准备工作之后,我们准备创建测试。为此,我们可以自己实现模拟:
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自动化模拟创建过程
关于unit-testing - 在 GOlang 中模拟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60979373/