断言:模拟:我不知道返回什么,因为方法调用是意外的。

huangapple go评论67阅读模式
英文:

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

huangapple
  • 本文由 发表于 2022年7月15日 09:58:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/72988347.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定