Home > front end >  assert: mock: I don't know what to return because the method call was unexpected
assert: mock: I don't know what to return because the method call was unexpected

Time:07-16

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)
     },
  • Related