英文:
assert: mock: I don't know what to return because the method call was unexpected
问题
我正在尝试使用testify在Go中创建一个单元测试。我要测试的函数非常简单,它会启动一个SQL事务,然后通过repo层从数据库中获取值,然后计算这些值。
但是每当我尝试运行单元测试时,我总是遇到这个错误。
# go test -v usecase/calculate_test.go usecase/calculate.go usecase/other_related_usecase.go
=== RUN Test_Calculate
[2022-07-15 08:42:30] INFO: Start Calculation
--- FAIL: Test_Calculate (0.00s)
panic:
assert: mock: I don't know what to return because the method call was unexpected.
Either do Mock.On("BeginTxx").Return(...) first, or remove the BeginTxx() call.
This method was unexpected:
BeginTxx()
at: [sql_repository.go:1 calculate.go:4 calculate_test.go:2] [recovered]
panic:
assert: mock: I don't know what to return because the method call was unexpected.
Either do Mock.On("BeginTxx").Return(...) first, or remove the BeginTxx() call.
This method was unexpected:
BeginTxx()
at: [sql_repository.go:1 calculate.go:4 calculate_test.go:2]
从我看到的情况来看,我认为它无法在单元测试中找到预期的方法调用。但是,问题在于我已经在onSQLMock
字段中定义了方法调用。
func Test_Calculate(t *testing.T) {
testCases := []struct {
name string
id int64
onSQLMock func(sqlMock *mocks.SQLRepository)
onOtherFuncMock func(otherFuncMock *mocks.OtherFuncMock)
wantError bool
expectedError string
}{
{
name: "Successfully Calculated",
onSQLMock: func(sqlMock *mocks.SQLRepository) {
var tx *sqlx.Tx
sqlRepo.On("BeginTxx").Return(tx, nil)
},
onOtherFuncMock: func(otherFuncMock *mocks.OtherFuncMock) {
// 在这里做一些操作
},
wantError: false,
},{
name: "Failed to calculate",
onSQLMock: func(sqlMock *mocks.SQLRepository) {
var tx *sqlx.Tx
sqlRepo.On("BeginTxx").Return(tx, errors.New("Failed to begin tx"))
},
onOtherFuncMock: func(otherFuncMock *mocks.OtherFuncMock) {
// 在这里做一些操作
},
wantError: true,
expectedError: "Failed to begin tx",
},
}
}
for _, testCase := range testCases {
uc := &usecase{
sqlRepo: new(mocks.SQLRepository),
otherFuncMock: new(mocks.OtherFuncMock),
}
actualErrx := uc.Calculate(context.Background(), testCase.id)
if testCase.wantError {
require.EqualError(t, actualErrx, testCase.expectedError)
}
}
}
func (_m *SQLRepository) BeginTxx() (*sqlx.Tx, error) {
ret := _m.Called()
var r0 *sqlx.Tx
if rf, ok := ret.Get(0).(func() *sqlx.Tx); ok {
r0 = rf()
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*sqlx.Tx)
}
}
var r1 error
if rf, ok := ret.Get(1).(func() error); ok {
r1 = rf()
} else {
r1 = ret.Error(1)
}
return r0, r1
}
有人能找出我的代码有什么问题吗?我无法找出原因,因为它看起来我已经按照错误提示的要求做了。
英文:
I'm trying to create a unit test on Go using testify. The function I'm trying to test is quite simple, it'll start an SQL transaction, and then get values from DB through the repo layer, and then calculate those values.
But whenever I'm trying to run the unit test, I always encountered this error.
# go test -v usecase/calculate_test.go usecase/calculate.go usecase/other_related_usecase.go
=== RUN Test_Calculate
[2022-07-15 08:42:30] INFO: Start Calculation
--- FAIL: Test_Calculate (0.00s)
panic:
assert: mock: I don't know what to return because the method call was unexpected.
Either do Mock.On("BeginTxx").Return(...) first, or remove the BeginTxx() call.
This method was unexpected:
BeginTxx()
at: [sql_repository.go:1 calculate.go:4 calculate_test.go:2] [recovered]
panic:
assert: mock: I don't know what to return because the method call was unexpected.
Either do Mock.On("BeginTxx").Return(...) first, or remove the BeginTxx() call.
This method was unexpected:
BeginTxx()
at: [sql_repository.go:1 calculate.go:4 calculate_test.go:2]
From what I see, I think it's becase it can't find the expected method call on the unit test. But, the problem is that I already defined the method call here inside the onSQLMock
field.
func Test_Calculate(t *testing.T) {
testCases := []struct {
name string
id int64
onSQLMock func(sqlMock *mocks.SQLRepository)
onOtherFuncMock func(otherFuncMock *mocks.OtherFuncMock)
wantError bool
expectedError string
}{
{
name: "Successfully Calculated",
onSQLMock: func(sqlMock *mocks.SQLRepository) {
var tx *sqlx.Tx
sqlRepo.On("BeginTxx").Return(tx, nil)
},
onOtherFuncMock: func(otherFuncMock *Mocks.OtherFuncMock) {
// do something here
},
wantError: false,
},{
name: "Failed to calculate",
onSQLMock: func(sqlMock *mocks.SQLRepository) {
var tx *sqlx.Tx
sqlRepo.On("BeginTxx").Return(tx, errors.New("Failed to begin tx")
},
onOtherFuncMock: func(otherFuncMock *mocks.OtherFuncMock) {
// do something here
},
wantError: true,
expectedError: "Failed to begin tx",
},
}
}
for _, testCase := range testCases {
uc := &usecase{
sqlRepo: new(mocks.SQLRepository),
otherFuncMock: new(mocks.OtherFuncMock),
}
actualErrx := uc.Calculate(context.Background(), testCase.id)
if testCase.wantError {
require.EqualError(t, actualErrx, testCase.expectedError)
}
}
}
func (_m *SQLRepository) BeginTxx() (*sqlx.Tx, error) {
ret := _m.Called()
var r0 *sqlx.Tx
if rf, ok := ret.Get(0).(func() *sqlx.Tx); ok {
r0 = rf()
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*sqlx.Tx)
}
}
var r1 error
if rf, ok := ret.Get(1).(func() error); ok {
r1 = rf()
} else {
r1 = ret.Error(1)
}
return r0, r1
}
Anyone can figure what was wrong on my code? I can't figure out because it looks like I already did what the error asked me to do.
答案1
得分: 1
你实际上没有在任何地方使用你的onSQLMock
。在将模拟存储库传递给usecase
实例之前,请使用它。
mockRepo := new(mocks.SQLRepository)
testCase.onSQLMock(mockRepo)
还要使用函数的参数:
onSQLMock: func(sqlMock *mocks.SQLRepository) {
var tx *sqlx.Tx
sqlMock.On("BeginTxx").Return(tx, nil)
},
英文:
You don't actually use your onSQLMock
anywhere.
Use it before you pass the mock repository to the usecase
instance
mockRepo := new(mocks.SQLRepository)
testCase.onSQLMock(mockRepo)
Also use the parameter of the function:
onSQLMock: func(sqlMock *mocks.SQLRepository) {
var tx *sqlx.Tx
sqlMock.On("BeginTxx").Return(tx, nil)
},
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论