【问题标题】:Cannot pass Testify Mock object error无法通过 Testify Mock 对象错误
【发布时间】:2018-06-09 08:00:58
【问题描述】:

您好,我正在尝试在 GO 中模拟一个结构。我正在使用作证来做到这一点。但我似乎无法让它发挥作用,现在也不知道我做错了什么。以下是我拥有的示例 main.go 和 main_test.go 文件

// Arithmetic ...
type Arithmetic interface {
    Add(int, int) int
    Subtract(int, int) int
}

// MathOperation ...
type MathOperation struct {}

// GetNewArithmetic ...
func GetNewArithmetic(obj Arithmetic) Arithmetic {
    if obj != nil {
        return obj
    }

    return MathOperation{}
}

// Add ...
func (a MathOperation) Add(num1 int, num2 int) int {
    return num1 + num2
}

// Subtract ...
func (a MathOperation) Subtract(num1 int, num2 int) int {
    return num1 - num2
}

这是我的测试文件

import (
    "testing"

    "github.com/stretchr/testify/assert"
    "github.com/stretchr/testify/mock"
)

type MyMock struct {
    mock.Mock
}

func (m *MyMock) Add(num1 int, num2 int) int {
    args := m.Called(num1, num2)
    return args.Int(0) + args.Int(1)
}

func (m *MyMock) Subtract(num1 int, num2 int) int {
    args := m.Called(num1, num2)
    return args.Int(0) + args.Int(1)
}

func TestDoComputation(t *testing.T) {
    testobj := new(MyMock)

    testobj.On("Add", 1, 2).Return(5)

    // a := GetNewArithmetic(testobj)

    result := GetNewArithmetic(testobj)

    assert.Equal(t, 5, result.Add(5, 6))
    testobj.AssertExpectations(t)
}

我收到此错误

--- FAIL: TestDoComputation (0.00s)
panic:

mock: Unexpected Method Call
-----------------------------

Add(int,int)
            0: 5
            1: 6

The closest call I have is:

Add(int,int)
            0: 1
            1: 2


 [recovered]
        panic:

mock: Unexpected Method Call
-----------------------------

Add(int,int)
            0: 5
            1: 6

The closest call I have is:

Add(int,int)
            0: 1
            1: 2

goroutine 13 [running]:
testing.tRunner.func1(0xc420106870)
        /usr/lib/golang/src/testing/testing.go:711 +0x2d2
panic(0x701160, 0xc420011070)

我不知道如何修复,因为这是我第一次使用 Go 并使用 Testify 进行单元测试。如果有人可以看看并有一个工作版本,将不胜感激。谢谢

【问题讨论】:

  • testobj.On("Add", 1, 2).Return(5) = 期望调用Add,参数为12,返回值5。实际调用result.Add(5, 6) 传递56。如您所知,这两个数字与12 不同。
  • 另外你模拟的是计算结果return args.Int(0) + args.Int(1),就像一个正常的实现一样。这不是你做模拟的方式。您的模拟应该返回它的第 0 个返回值,即您传递给 Return 方法 (5) 的那个。所以模拟返回语句实际上应该是return args.Int(0)
  • 另外,请理解 args 值包含指定的 return 参数(传递给 Return 方法的参数),args 确实不持有输入参数。
  • @mkopriva 非常感谢您指出这个参数和参数。因为老实说我不知道​​它是做什么的,我只是从在线教程中复制并做了一些修改。感谢您澄清这一点。您能否将您的答案移至实际答案,以便我可以将其批准为解决方案

标签: go testify


【解决方案1】:

线

testobj.On("Add", 1, 2).Return(5)

意味着您希望 testobj 模拟接收对其 Add 方法的调用,其中参数 12 传递给它,并且您还指定该调用应返回整数值 5 .

而是在这一行

assert.Equal(t, 5, result.Add(5, 6))

您正在使用参数56 调用方法Add

这会导致你得到的错误:

mock: Unexpected Method Call
-----------------------------

Add(int,int)
            0: 5
            1: 6
// this is result.Add(5, 6), the 0: and 1: are indexes of the actually passed in aguments.

The closest call I have is:

Add(int,int)
            0: 1
            1: 2
// this is testobj.On("Add", 1, 2), and 0: and 1: are indexes of the expected arguments.

最重要的是,您的模拟实现正在尝试计算并返回该值。这不是模拟应该做的。模拟应该返回通过Return 方法提供给它的值。

执行此操作的方法是使用从Called 方法调用返回的args 值,该值将保存Return 方法的参数,其索引顺序与它们传递给Return 的顺序相同。

所以你在这一行传递给Return的整数值5

testobj.On("Add", 1, 2).Return(5)

可以使用Int 实用方法访问并将其传递给第 0 个索引。即return args.Int(0) 将返回整数值5

所以你的测试文件应该看起来更像这样:

import (
    "testing"

    "github.com/stretchr/testify/assert"
    "github.com/stretchr/testify/mock"
)

type MyMock struct {
    mock.Mock
}

func (m *MyMock) Add(num1 int, num2 int) int {
    args := m.Called(num1, num2)
    return args.Int(0)
}

func (m *MyMock) Subtract(num1 int, num2 int) int {
    args := m.Called(num1, num2)
    return args.Int(0)
}

func TestDoComputation(t *testing.T) {
    testobj := new(MyMock)

    testobj.On("Add", 1, 2).Return(5)

    // a := GetNewArithmetic(testobj)

    result := GetNewArithmetic(testobj)

    assert.Equal(t, 5, result.Add(1, 2))
    testobj.AssertExpectations(t)
}

【讨论】:

    【解决方案2】:

    在 testify/mock 包中

    testobj.On("Add", 1, 2).Return(5)

    在上面的行中,它告诉模拟对象,每当我们使用以下参数调用 Add 方法时,它应该返回 5。return 用于将结果传递给具有给定参数的方法。

    assert.Equal(t, 5, result.Add(5, 6))

    在这一行中,您要求将预期结果与函数调用相匹配。之前您指定当您传递 1 和 2 时,该函数应返回 5,但在 Equal 语句中您传递的值是 5 和 6

    您所要做的就是用正确的值更改任何一行。

    testobj.On("Add", 5, 6).Return(5)

    【讨论】:

      猜你喜欢
      • 2013-03-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-23
      相关资源
      最近更新 更多