亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何在同一結構中的另一個方法中調用存根方法

如何在同一結構中的另一個方法中調用存根方法

Go
一只斗牛犬 2022-06-06 15:53:14
代碼在這里:package mainimport (  "fmt")type Connector struct {}func (c *Connector) Pool() (interface{}, error) {  err := c.ping()  if err != nil {    fmt.Println("error handle logic");    return nil, err  }  fmt.Println("success logic")  return 1, nil}func (c *Connector) ping() error {  var err error  // err = some side-effect RPC operation  if err != nil {    return err  }  return nil}現在,我想測試一下struct的Pool方法。Connector由于該ping方法有一些副作用 RPC 操作,我需要對它及其返回值進行存根,以便我可以測試該Pool方法中的每個代碼分支。成功測試用例偽代碼:Stub(c, "ping").Return(nil)c.Pool()Expect(fmt.Println).ToBeCalledWith("success logic")失敗測試用例偽代碼:Stub(c, "ping").Return(errors.New("test"))c.Pool()Expect(fmt.Println).ToBeCalledWith("error handle logic")
查看完整描述

1 回答

?
慕桂英546537

TA貢獻1848條經驗 獲得超10個贊

我們需要遵循依賴倒置原則,這將使代碼更容易測試。


細節(具體實現)應該依賴于抽象。


重構代碼:


connector.go:


package connector


import (

    "fmt"

)


type Pinger interface {

    Ping() error

}


type Connector struct {

    DB Pinger

}


func (c *Connector) Pool() (interface{}, error) {

    err := c.DB.Ping()

    if err != nil {

        fmt.Println("error handle logic")

        return nil, err

    }

    fmt.Println("success logic")

    return 1, nil

}

現在,使用stretchr/testify包創建實現Pinger接口的模擬數據庫。然后,將這個模擬的 DB 傳遞給struct,這是某種依賴注入。Connector


然后我們可以“模擬”Ping具有不同返回值的方法。


connector_test.go:


package connector_test


import (

    "fmt"

    "testing"


    connector "github.com/mrdulin/golang/src/stackoverflow/62035606"

    "github.com/stretchr/testify/mock"

    "github.com/stretchr/testify/require"

)


type MockedDB struct {

    mock.Mock

}


func (db *MockedDB) Ping() error {

    args := db.Called()

    return args.Error(0)

}


func TestConnector_Pool(t *testing.T) {

    t.Run("should verifies connection to the database is still alive", func(t *testing.T) {

        testDB := new(MockedDB)

        c := connector.Connector{DB: testDB}

        testDB.On("Ping").Return(nil)

        pool, err := c.Pool()

        require.Nil(t, err, nil)

        require.Equal(t, 1, pool)

    })


    t.Run("should return error if connection to the database is not alive", func(t *testing.T) {

        testDB := new(MockedDB)

        c := connector.Connector{DB: testDB}

        testDB.On("Ping").Return(fmt.Errorf("network"))

        pool, err := c.Pool()

        require.Error(t, err, "network")

        require.Nil(t, pool)

    })

}

單元測試結果:


=== RUN   TestConnector_Pool

=== RUN   TestConnector_Pool/should_verifies_connection_to_the_database_is_still_alive

success logic

=== RUN   TestConnector_Pool/should_return_error_if_connection_to_the_database_is_not_alive

error handle logic

--- PASS: TestConnector_Pool (0.00s)

    --- PASS: TestConnector_Pool/should_verifies_connection_to_the_database_is_still_alive (0.00s)

    --- PASS: TestConnector_Pool/should_return_error_if_connection_to_the_database_is_not_alive (0.00s)

PASS

coverage: 100.0% of statements

ok      github.com/mrdulin/golang/src/stackoverflow/62035606    0.364s

覆蓋報告:

http://img1.sycdn.imooc.com//629db2880001636416720987.jpg

查看完整回答
反對 回復 2022-06-06
  • 1 回答
  • 0 關注
  • 117 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號