在Go中,我将如何测试以正确的方式调用了模拟依赖项。
如果我有一个采用依赖关系接口的结构,那么在注入后,我希望能够测试原始的模拟对象。
在此示例中,我当前的代码看不到struct值已更改。如果我将代码更改为通过引用传递,则会触发错误:
s.simpleInterface.Call不确定(类型* SimpleInterface是指向接口而不是接口的指针)
type SimpleInterface interface {
Call()
}
type Simple struct {
simpleInterface SimpleInterface
}
func (s Simple) CallInterface() {
s.simpleInterface.Call()
}
type MockSimple struct {
hasBeenCalled bool
}
func (ms MockSimple) Call() {
ms.hasBeenCalled = true
}
func TestMockCalled(t *testing.T) {
ms := MockSimple{}
s := Simple{
simpleInterface: ms,
}
s.CallInterface()
if ms.hasBeenCalled != true {
t.Error("Interface has not been called")
}
}
答案 0 :(得分:3)
我看到三种简单的方法来解决此问题:
1-更改Call方法的签名以接收指向MockSimple的指针,并在实例化Simple结构时为其提供模拟地址:
func (ms *MockSimple) Call() {
ms.hasBeenCalled = true
}
func TestMockCalled(t *testing.T) {
ms := MockSimple{}
s := Simple{
simpleInterface: &ms,
}
s.CallInterface()
if ms.hasBeenCalled != true {
t.Error("Interface has not been called")
}
}
2-不是最干净的解决方案,但仍然有效。如果您真的不能使用#1,请使用它。在其他地方声明“ hasBeenCalled”,然后更改您的MockSimple使其指向指针:
type MockSimple struct {
hasBeenCalled *bool
}
func (ms MockSimple) Call() {
*ms.hasBeenCalled = true
}
func TestMockCalled(t *testing.T) {
hasBeenCalled := false
ms := MockSimple{&hasBeenCalled}
s := Simple{
simpleInterface: ms,
}
s.CallInterface()
if hasBeenCalled != true {
t.Error("Interface has not been called")
}
}
3-可能是一个非常糟糕的解决方案:使用全局变量,因此我只会将其用作最后的手段(始终避免使用全局状态)。将“ hasBeenCalled”设置为全局变量,然后从方法中对其进行修改。
var hasBeenCalled bool
type MockSimple struct{}
func (ms MockSimple) Call() {
hasBeenCalled = true
}
func TestMockCalled(t *testing.T) {
ms := MockSimple{}
s := Simple{
simpleInterface: ms,
}
s.CallInterface()
if hasBeenCalled != true {
t.Error("Interface has not been called")
}
}
干杯!