在Golang测试中将模拟对象作为参数传递

huangapple go评论76阅读模式
英文:

Passing mock as argument in Golang test

问题

这是我正在测试的代码:

func listObjects(cli *client.Client, options clientOptions) ([]BlobObjects, error) {
    objects, err := cli.ListBlobObjects(...)
}

在我的测试设置中,我这样做:

type MockClient struct {
    MockListBlobObjects func() ([]BlobObjects, error)
}

func (m *MockClient) ListBlobObjects(...) ([]BlobObjects, error) {
    // 返回一些模拟的响应
}

这是我的测试用例:

func TestBlobObjects(t *testing.T) {
    tests := map[string]struct {
        client         *MockClient
        ...
    }{
        "Test case 1": {
            client: &MockClient{
                MockListBlobObjects: ...,
            },
            ...
        },
        ...
    }

    for testName, test := range tests {
        blobs, err := listObjects(test.client, clientOptions{})
        // 在这里进行断言
    }
}

问题是test.client。编译器告诉我:

无法将类型为*MockClient的test.client作为参数传递给listObjects中类型为*client.Client的变量

我希望我有一个模拟客户端,如果我调用被测试的函数,那么传递的模拟客户端将调用模拟的listObjects函数。在Python中,我会这样做。

在Golang中我该怎么做?

英文:

This is the code I am testing

func listObjects(cli *client.Client, options clientOptions) ([]BlobObjects, error) {
    objects, err := cli.ListBlobObjects(...)
}

In my test setup I do this

type MockClient struct {
	MockListBlobObjects func() ([]BlobObjects, error)
}

func (m *MockClient) ListBlobObjects(....) ([]BlobObjects, error) {
    // return some mock response
}

And this is my test case

func TestBlobObjects(t *testing.T) {
	tests := map[string]struct {
		client         *MockClient
        ...
	}{
		"Test case 1": {
			client: &MockClient{
				MockListBlobObjects: ....,
			},
			....
		},

      ....
   for testName, test := range tests {
      blobs, err := (test.client, clientOptions{})
      // make assertions here
   }

The problem is test.client. Compiler is telling me

cannot use test.client (variable of type *MockClient) as *client.Client value in argument to listObjects

My hope was I have a mock client and if I call the function under test, then the mock client passed will call the mocked listObjects. This is how I would do in Python.

What should I do in Golang?

答案1

得分: 2

你需要创建一个公共接口,这个接口将由两种类型实现。

type Client interface {
    ListBlobObjects() ([]BlobObjects, error)
}

type RealClient struct {
}

func (c *RealClient) ListBlobObjects(....) ([]BlobObjects, error) {
    // 返回一些响应
}

type MockClient struct {
  // 注意:不要在函数体中放置方法签名
}

func (m *MockClient) ListBlobObjects(....) ([]BlobObjects, error) {
    // 返回一些模拟响应
}

然后

var client client.Client
client = &RealClient{}
// 或者
client = &MockClient{}
英文:

You need to create a common interface, which will be implemented by both types

type Client interface {
    ListBlobObjects func() ([]BlobObjects, error)
}

type RealClient struct {
}

func (c *RealClient) ListBlobObjects(....) ([]BlobObjects, error) {
    // return some response
}

type MockClient struct {
  // note: don't put method signature in function body
}

func (m *MockClient) ListBlobObjects(....) ([]BlobObjects, error) {
    // return some mock response
}

and then

var client client.Client
client = &RealClient{}
// or
client = &MockClient{}

huangapple
  • 本文由 发表于 2022年9月20日 21:18:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/73787383.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定