Go语言 模拟awsEventStream

6rvt4ljy  于 2023-06-27  发布在  Go
关注(0)|答案(2)|浏览(146)

我有一个如下的函数,我试着模仿AWS S3的selectobjectcontentoutput,但都是徒劳的。我甚至试过s3fice,它说:包s3iface提供了一个接口,用于模拟Amazon Simple Storage Service服务客户端,以测试您的代码。

func awsEventStream(resp *s3.SelectObjectContentOutput) string {

    ---

    return awsResponse

}

我试图写测试用例为上述如下,有各种methopds在s3,但我需要模拟只在我的主类中使用的方法。

package main

import (
    "github.com/aws/aws-sdk-go/service/s3"
    "testing"
)

type SelectObjectContentOutput struct {
    s3.SelectObjectContentOutput
}

func (m *SelectObjectContentOutput) EventStream(input *s3.SelectObjectContentInput) (*s3.SelectObjectContentOutput, error) {
    output := &s3.SelectObjectContentOutput{
        EventStream: nil,
    }
    return output, nil
}

func TestAwsEventStream(t *testing.T) {
    mockSvc := &SelectObjectContentOutput{}
    awsEventStream(&mockSvc.SelectObjectContentOutput)

}
hlswsv35

hlswsv351#

无法模拟SelectObjectContentOutput。我们得到的EventStream为null。
创建s3.SelectObjectContentOutput时,需要指定EventStream属性。阅读s3 SelectObjectContentEventStream文档:
为了测试和模拟事件流,应该通过NewSelectObjectContentEventStream构造函数初始化此类型。使用函数选项传入嵌套的模拟行为。
文档还包括如何使用NewSelectObjectContentEventStream的示例。

es := NewSelectObjectContentEventStream(func(o *SelectObjectContentEventStream){
    o.Reader = myMockStreamReader
    o.StreamCloser = myMockStreamCloser
})

对于这个问题,我们可以通过将StreamCloser设置为空ReadCloser来忽略它。
设置Reader SelectObjectContentEventStreamReader会比较麻烦,因为它是一个接口,而且从外观上看,s3并没有提供一种直接构造读取器的方法。我们可以创建一个类型来实现它:

type stubSelectObjectContentEventStreamReader struct {
    StreamEvents <-chan s3.SelectObjectContentEventStreamEvent
    Error        error
}

func (s stubSelectObjectContentEventStreamReader) Events() <-chan s3.SelectObjectContentEventStreamEvent {
    return s.StreamEvents
}

func (s stubSelectObjectContentEventStreamReader) Close() error {
    return nil
}

func (s stubSelectObjectContentEventStreamReader) Err() error {
    return s.Error
}

把这些放在一起:

func TestAwsEventStream(t *testing.T) {
    streamEvents := make(chan s3.SelectObjectContentEventStreamEvent, 3)
    eventStreamReader := stubSelectObjectContentEventStreamReader{
        StreamEvents: streamEvents,
        Error:        nil,
    }

    mockEventStream := s3.NewSelectObjectContentEventStream(func(o *s3.SelectObjectContentEventStream) {
        o.Reader = eventStreamReader
        o.StreamCloser = io.NopCloser(bytes.NewReader(nil))
    })

    mockOutput := &s3.SelectObjectContentOutput{
        EventStream: mockEventStream,
    }

    streamEvents <- &s3.RecordsEvent{Payload: []byte("hello world")}
    streamEvents <- &s3.EndEvent{}
    close(streamEvents)

    got := awsEventStream(mockOutput)
    want := "hello world"

    if got != want {
        t.Errorf("got %v, want %v", got, want)
    }
}
mfuanj7w

mfuanj7w2#

@wijayaerick给出的答案是合适的,应该涵盖了大约60%的代码。但是如果OP想要100%覆盖测试用例,那么他需要遍历所有的switch case语句。下面是我的代码,我已经尝试过,它的工作需要。
你需要改变的几件事是:
使通道大小为3streamEvents := make(chan s3.SelectObjectContentEventStreamEvent, 3)
RecordsEventEndEventStatsEvent添加到streamEvents,如下所示:

statsEvent := &s3.StatsEvent{
    Details: &s3.Stats{
        BytesScanned:   aws.Int64(1024),
        BytesProcessed: aws.Int64(2048),
    },
}
streamEvents <- &s3.RecordsEvent{Payload: []byte("hello world")}
streamEvents <- &s3.EndEvent{}
streamEvents <- statsEvent

您的整体代码如下所示:

package main

import (
    "bytes"
    "github.com/aws/aws-sdk-go/aws"
    "github.com/aws/aws-sdk-go/service/s3"
    "io"
    "testing"
)

type stubSelectObjectContentEventStreamReader struct {
    StreamEvents <-chan s3.SelectObjectContentEventStreamEvent
    Error        error
}

func (s stubSelectObjectContentEventStreamReader) Events() <-chan s3.SelectObjectContentEventStreamEvent {
    return s.StreamEvents
}

func (s stubSelectObjectContentEventStreamReader) Close() error {
    return nil
}

func (s stubSelectObjectContentEventStreamReader) Err() error {
    return s.Error
}

func TestAwsEventStream(t *testing.T) {

    type testCase struct {
        arg1 s3.SelectObjectContentEventStreamEvent
        want s3.SelectObjectContentEventStreamEvent
    }
    streamEvents := make(chan s3.SelectObjectContentEventStreamEvent, 3)
    eventStreamReader := stubSelectObjectContentEventStreamReader{
        StreamEvents: streamEvents,
        Error:        nil,
    }

    mockEventStream := s3.NewSelectObjectContentEventStream(func(o *s3.SelectObjectContentEventStream) {
        o.Reader = eventStreamReader
        o.StreamCloser = io.NopCloser(bytes.NewReader(nil))
    })

    mockOutput := &s3.SelectObjectContentOutput{
        EventStream: mockEventStream,
    }
    statsEvent := &s3.StatsEvent{
        Details: &s3.Stats{
            BytesScanned:   aws.Int64(1024),
            BytesProcessed: aws.Int64(2048),
        },
    }
    streamEvents <- &s3.RecordsEvent{Payload: []byte("hello world")}
    streamEvents <- &s3.EndEvent{}
    streamEvents <- statsEvent
    close(streamEvents)

    got := awsEventStream(mockOutput)
    want := "hello world"

    if got != want {
        t.Errorf("got %v, want %v", got, want)
    }
}

相关问题