我正在编写单元测试,并且我想编写一个单元测试来断言结构(Foo.Start
)上的公共方法正确处理了结构({{1})上来自内部方法的错误响应}。
基本上,我想对我的代码这一部分进行测试:
Foo.internal
这是一个不起作用的代码和相关测试的示例(但在Python中会起作用)
if err != nil {
return err
}
# example.go
package example
import "fmt"
type FooAPI interface {
Start() error
internal(string) (string, error)
}
type Foo struct {
FooAPI
}
func (foo Foo) Start() (err error) {
data, err := foo.internal("bar")
if err != nil {
return err
}
fmt.Println(data)
return err
}
func (foo Foo) internal(input string) (output string, err error) {
return output, err
}
我对更正特定示例的兴趣不大,因此我的目标是对# example_test.go
package example
import (
"testing"
"github.com/pkg/errors"
)
type MockFoo struct {
FooAPI
}
func (foo MockFoo) internal(input string) (output string, err error) {
return output, errors.New("big error")
}
func TestStart(t *testing.T) {
tdata := []struct {
testCase string
expectedAnError bool
foo FooAPI
}{
{
testCase: "standard_case",
expectedAnError: false,
foo: Foo{},
},
{
testCase: "error_case",
expectedAnError: true,
foo: MockFoo{},
},
}
for _, test := range tdata {
t.Run(test.testCase, func(t *testing.T) {
// The function under test
test.foo.Start = Foo.Start // <= this doesn't work
err := test.foo.Start()
// Assertion 1
if test.expectedAnError == false && err != nil {
t.Error(err.Error())
}
// Assertion 2
if test.expectedAnError == true && err == nil {
t.Error("expected an error, but there was none!")
}
})
}
}
的错误处理进行测试。我觉得接口或指针有一些技巧可以使我在终点线?
答案 0 :(得分:0)
我想出了一个受https://stackoverflow.com/a/48206430/3055558启发的解决方案
使用internal{{ your struct }}
结构和关联的接口,并对其进行模拟。
# example.go
package example
import "fmt"
type internalFooAPI interface {
internalBehavior(string) (string, error)
}
type Foo struct {
internal internalFooAPI
}
type internalFoo struct{}
func NewFoo(internal internalFooAPI) Foo {
return Foo{
internal: internal,
}
}
func (foo Foo) Start() (err error) {
data, err := foo.internal.internalBehavior("bar")
if err != nil {
return err
}
fmt.Println(data)
return err
}
func (foo internalFoo) internalBehavior(input string) (output string, err error) {
return output, err
}
# example_test.go
package example
import (
"testing"
"github.com/pkg/errors"
)
type mockInternalFoo struct{}
type mockInternalFooWithErrors struct{}
func (foo mockInternalFoo) internalBehavior(input string) (output string, err error) {
return output, err
}
func (foo mockInternalFooWithErrors) internalBehavior(input string) (output string, err error) {
return output, errors.New("big error")
}
func TestStart(t *testing.T) {
tdata := []struct {
testCase string
expectedAnError bool
foo Foo
}{
{
testCase: "standard_case",
expectedAnError: false,
foo: NewFoo(internalFoo{}),
},
{
testCase: "mock_case",
expectedAnError: false,
foo: NewFoo(mockInternalFoo{}),
},
{
testCase: "error_case",
expectedAnError: true,
foo: NewFoo(mockInternalFooWithErrors{}),
},
}
for _, test := range tdata {
t.Run(test.testCase, func(t *testing.T) {
// The function under test
err := test.foo.Start()
// Assertion 1
if test.expectedAnError == false && err != nil {
t.Error(err.Error())
}
// Assertion 2
if test.expectedAnError == true && err == nil {
t.Error("expected an error, but there was none!")
}
})
}
}