为了账号安全,请及时绑定邮箱和手机立即绑定

如何为从外部包导入的方法创建单元测试期望?

如何为从外部包导入的方法创建单元测试期望?

Go
慕尼黑8549860 2023-01-03 15:51:02
我有这个功能,我想测试。我使用 testify 创建单元测试。// calculate.goimport (  "context"  "errors"  "testing"  "github.com/jmoiron/sqlx")func (u usecase) CalculateTransaction(ctx context.Context, ID int64) (err error) {  // tx has the type of `*sqlx.Tx`, which I got from that imported package above  tx, err := u.sqlRepo.BeginTX()  if err != nil {    return err  }  defer func() {    if tx != nil {    err = tx.Rollback()      if err != nil {        return err      }    }  }    err = tx.Commit()  if err != nil {    return err  }  return nil}这应该是单元测试// calculate_test.gofunc TestCalculate(t *testing.T) {  var tx *sqlx.Tx  var expectedError string  mockSQL = new(mocks.SQLRepository)  mockSQL.On("BeginTX").Return(tx, nil)  // mock tx.Commit() here  // mock tx.Rollback() here  usecase := &calculationUsecase{    sqlRepo: mockSQL  }  actualError := usecase.CalculateTransaction(context.Background(), 1)  require.EqualError(t, actualError, expectedError)}我的问题是tx.Commit()和tx.Rollback()方法。如果我以这种方式运行它,我会得到一个invalid memory address or nil pointer dereference错误,这是有道理的,因为我没有为那些方法调用设置期望。但我不知道如何创建它。这些方法本身是从外部包导入的,即"github.com/jmoiron/sqlx". 我不确定我是否需要为位于根目录的外部包创建一个模拟对象,或者是否有另一种方法可以做到这一点而不必模拟它。任何人都可以告诉我如何解决这个问题或如何设置期望?我不知道我能不能做到,但我也试过像这样将单元测试(使用 testify)与 DataDog 的 sqlmock 结合起来
查看完整描述

1 回答

?
忽然笑

TA贡献1806条经验 获得超5个赞

在您的测试中,您在数据库提供者级别模拟数据库,不再需要模拟。


没有冗余模拟的测试:


func TestCalculate(t *testing.T) {

  

  // transaction is created inside `CalculateTransaction`, it will be started against mocked DB

  // var tx *sqlx.Tx

  var expectedError string


  dbMock, mock, err := sqlmock.New()

  if err != nil {

    t.Fatalf("an error '%s' was not expected", err)

  }

  defer dbMock.Close()


  // we use sql mock - no need to mock DB methods

  // mockSQL = new(mocks.SQLRepository)

  // mockSQL.On("BeginTX").Return(tx, nil)

  

  mock.ExpectCommit()


  // here you can add ExpectQuery or ExpectExec if usecase do any DB work


  mock.ExpectRollback()


  usecase := &calculationUsecase{

    sqlRepo: dbMock

  }


  actualError := usecase.CalculateTransaction(context.Background(), 1)

  require.EqualError(t, actualError, expectedError)


  // it is good practice to check is all expectations are met

  err = mock.ExpectationsWereMet()

  require.NoError(t, err)

}


查看完整回答
反对 回复 2023-01-03
  • 1 回答
  • 0 关注
  • 54 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信