模拟 awsEventStream

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

Mock awsEventStream

问题

我有一个如下的函数,我尝试模拟 aws s3 selectobjectcontentoutput,但都没有成功。我甚至尝试了 s3fice,它说:s3iface 包提供了一个接口,用于在测试代码时模拟 Amazon Simple Storage Service 服务客户端。

func awsEventStream(resp *s3.SelectObjectContentOutput) string {

---

return awsResponse

}

我正在尝试编写上述函数的测试用例,如下所示,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)

}
英文:

I have a function as below, I have tried mocking the aws s3 selectobjectcontentoutput but all in vain. I have even tried s3fice which says: Package s3iface provides an interface to enable mocking the Amazon Simple Storage Service service client for testing your code.

    func awsEventStream(resp *s3.SelectObjectContentOutput) string {

    ---

    return awsResponse

}

I am trying to write test case for the above as below, there are various methopds in s3 but I eed to mock only the method used in my main class.

    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)

}

答案1

得分: 4

无法模拟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)
	}
}
英文:

> Not able to mock SelectObjectContentOutput. We are getting the EventStream as null.

When creating s3.SelectObjectContentOutput, you need to specify the EventStream attribute. From reading the s3 SelectObjectContentEventStream docs:
> For testing and mocking the event stream this type should be initialized via the NewSelectObjectContentEventStream constructor function. Using the functional options to pass in nested mock behavior.

The docs also include example on how to use NewSelectObjectContentEventStream.

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

For this question, we can ignore StreamCloser by setting it to empty ReadCloser.

Setting the Reader SelectObjectContentEventStreamReader will be trickier because it is an interface and from the look of it, s3 does not provide a direct way to construct the reader. Thought we can just create a type that implements it:

type stubSelectObjectContentEventStreamReader struct {
	StreamEvents &lt;-chan s3.SelectObjectContentEventStreamEvent
	Error        error
}

func (s stubSelectObjectContentEventStreamReader) Events() &lt;-chan s3.SelectObjectContentEventStreamEvent {
	return s.StreamEvents
}

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

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

Putting it all together:

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 := &amp;s3.SelectObjectContentOutput{
		EventStream: mockEventStream,
	}

	streamEvents &lt;- &amp;s3.RecordsEvent{Payload: []byte(&quot;hello world&quot;)}
    streamEvents &lt;- &amp;s3.EndEvent{}
	close(streamEvents)

	got := awsEventStream(mockOutput)
	want := &quot;hello world&quot;

	if got != want {
		t.Errorf(&quot;got %v, want %v&quot;, got, want)
	}
}

答案2

得分: 2

@wijayaerick给出的答案是正确的,应该涵盖了大约60%的代码。但是,如果OP想要覆盖100%的测试用例,那么他需要遍历所有的switch case语句。以下是我尝试过的代码,它按需工作。

你需要更改的几个地方是:

将通道大小更改为3 streamEvents := 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)
	}
}

模拟 awsEventStream

英文:

The answer given by @wijayaerick is appropriate and should cover around 60% of the code. But in case OP wants to cover the test case to 100% then he needs to traverse all the switch case statements. Below is my code that I have tried and it works as needed.

Few things that you would need to change is:

Make channel size to 3 streamEvents := make(chan s3.SelectObjectContentEventStreamEvent, 3)

Add RecordsEvent, EndEvent and StatsEvent to streamEvents as below:

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

Your overall code will look like below:

package main
import (
&quot;bytes&quot;
&quot;github.com/aws/aws-sdk-go/aws&quot;
&quot;github.com/aws/aws-sdk-go/service/s3&quot;
&quot;io&quot;
&quot;testing&quot;
)
type stubSelectObjectContentEventStreamReader struct {
StreamEvents &lt;-chan s3.SelectObjectContentEventStreamEvent
Error        error
}
func (s stubSelectObjectContentEventStreamReader) Events() &lt;-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 := &amp;s3.SelectObjectContentOutput{
EventStream: mockEventStream,
}
statsEvent := &amp;s3.StatsEvent{
Details: &amp;s3.Stats{
BytesScanned:   aws.Int64(1024),
BytesProcessed: aws.Int64(2048),
},
}
streamEvents &lt;- &amp;s3.RecordsEvent{Payload: []byte(&quot;hello world&quot;)}
streamEvents &lt;- &amp;s3.EndEvent{}
streamEvents &lt;- statsEvent
close(streamEvents)
got := awsEventStream(mockOutput)
want := &quot;hello world&quot;
if got != want {
t.Errorf(&quot;got %v, want %v&quot;, got, want)
}
}

模拟 awsEventStream

huangapple
  • 本文由 发表于 2023年6月12日 23:47:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/76458292.html
匿名

发表评论

匿名网友

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

确定