donglian1982
2018-06-09 08:00
浏览 72
已采纳

无法通过Testify Mock对象错误

Hi I'm trying to mock a struct in GO. I'm using testify to do this. But I can't seem to get it to work and don't now what I'm doing wrong. Below is the sample main.go and main_test.go file I have

// 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
}

And here is my test file

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)
}

I receive this error

--- 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)

I have no idea on how to fix since this is my first time using Go and using Testify to do unit testing. Would appreciate if someone can take a look and have a working version of this. Thanks

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

2条回答 默认 最新

  • dq8081 2018-06-09 09:48
    已采纳

    The line

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

    means that you expect the testobj mock to receive a call to its Add method with arguments 1 and 2 passed to it, and you also specify that that call should return the integer value 5.

    But instead on this line

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

    you are calling the method Add with arguments 5 and 6.

    This results in the error you got:

    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.
    

    On top of that your mock implementations are attempting to calculate and return the value. This is not what a mock should do. A mock should instead return the value provided to it through the Return method.

    The way you can do this is by using the args value returned from the Called method call, this value will hold the Return method's arguments indexed in the same order they were passed in to Return.

    So the integer value 5 that you passed to Return on this line

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

    can be accessed using the Int utility method and passing it the 0th index. That is return args.Int(0) will return the interger value 5.

    So your test file should look more like this:

    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)
    }
    
    点赞 评论
  • dqphg40600 2018-11-29 05:53

    In testify/mock package

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

    In above line,It tell the mock object that whenever we Call Add method with following arguments,it should return 5. Return is used to pass the result to the method with the given arguments.

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

    In this line,you are asking to match the expected result with the function call.Earlier you specify when you pass 1 & 2,the function should return 5 but in Equal statement you are passing values 5 & 6

    All you have to is the change any of the one line with the correct value.

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

    点赞 评论

相关推荐 更多相似问题