1 回答

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
覆蓋報告:
- 1 回答
- 0 關注
- 117 瀏覽
添加回答
舉報