gpt4 book ai didi

unit-testing - 如何在同一结构中的另一个方法中调用 stub 方法

转载 作者:行者123 更新时间:2023-12-01 21:13:41 24 4
gpt4 key购买 nike

代码在这里:

package main

import (
"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
}

现在,我想测试 Pool Connector的方法结构。由于 ping方法有一些副作用 RPC 操作,我需要 stub 它及其返回值,以便我可以测试 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")

最佳答案

我们需要关注 Dependency inversion principle ,它将使代码更易于测试。

Details (concrete implementations) should depend on abstractions.


重构代码: 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
}
现在,创建实现 Pinger 的模拟数据库。接口(interface)使用 stretchr/testify包裹。然后,将此模拟数据库传递给 Connector struct,它是某种依赖注入(inject)。
然后我们可以“模拟” 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
覆盖报告:
enter image description here

关于unit-testing - 如何在同一结构中的另一个方法中调用 stub 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62035606/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com