Unit testing 使用以下方法测试错误响应';结构的内部

Unit testing 使用以下方法测试错误响应';结构的内部,unit-testing,go,Unit Testing,Go,我正在编写单元测试,我想编写一个单元测试,它断言结构(Foo.Start)上的公共方法正确地处理来自结构(Foo.internal)上的内部方法的错误响应 基本上,我希望在代码的这一部分中获得测试覆盖率: 如果出错!=零{ 返回错误 } 下面是一个不起作用的代码和相关测试示例(但可以在Python中工作) #example.go 包示例 输入“fmt” 类型FooAPI接口{ Start()错误 内部(字符串)(字符串,错误) } 类型Foo struct{ 福奥皮 } func(foo-fo

我正在编写单元测试,我想编写一个单元测试,它断言结构(
Foo.Start
)上的公共方法正确地处理来自结构(
Foo.internal
)上的内部方法的错误响应

基本上,我希望在代码的这一部分中获得测试覆盖率:

如果出错!=零{
返回错误
}
下面是一个不起作用的代码和相关测试示例(但可以在Python中工作)

#example.go
包示例
输入“fmt”
类型FooAPI接口{
Start()错误
内部(字符串)(字符串,错误)
}
类型Foo struct{
福奥皮
}
func(foo-foo)Start()(错误){
数据,错误:=foo.internal(“bar”)
如果错误!=零{
返回错误
}
fmt.Println(数据)
返回错误
}
func(foo-foo)内部(输入字符串)(输出字符串,错误){
返回输出,错误
}
#示例_test.go
包示例
进口(
“测试”
“github.com/pkg/errors”
)
类型MockFoo struct{
福奥皮
}
func(foo MockFoo)内部(输入字符串)(输出字符串,错误){
返回输出,errors.New(“大错误”)
}
func TestStart(t*testing.t){
tdata:=[]结构{
测试用例字符串
预期错误布尔
福福阿皮
}{
{
testCase:“标准案例”,
预期错误:false,
foo:foo{},
},
{
testCase:“错误案例”,
预期错误:正确,
foo:MockFoo{},
},
}
对于u,测试:=范围tdata{
t、 运行(test.testCase,func(t*testing.t){
//正在测试的功能

test.foo.Start=foo.Start/我想出了一个解决方案,灵感来自

使用
内部{{your struct}}
struct和相关接口,并模拟该接口

#example.go
包示例
输入“fmt”
类型为internalFooAPI接口{
内部行为(字符串)(字符串,错误)
}
类型Foo struct{
内部fooapi
}
类型internalFoo struct{}
func NewFoo(内部fooapi)Foo{
返回Foo{
内部:内部,,
}
}
func(foo-foo)Start()(错误){
数据,错误:=foo.internal.internalBehavior(“bar”)
如果错误!=零{
返回错误
}
fmt.Println(数据)
返回错误
}
func(foo internalFoo)internalBehavior(输入字符串)(输出字符串,err error){
返回输出,错误
}
# 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!")
            }
        })
    }
}
# 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!")
            }
        })
    }
}