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.
CodePudding user response:
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)
},