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

我有这个功能,我想测试。我使用 testify 创建单元测试。


// calculate.go

import (

  "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.go

func 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 结合起来


慕尼黑8549860
浏览 55回答 1
1回答

忽然笑

在您的测试中,您在数据库提供者级别模拟数据库,不再需要模拟。没有冗余模拟的测试: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)}
打开App,查看更多内容
随时随地看视频慕课网APP