英文:
What could be a unit test case for the s3/sqs event when unmarshalling json to struck in Go Lang?
问题
对于在Go中将JSON解组为结构体的S3/SQS事件,可能的单元测试用例是什么?
一个我想到的选项是,如果"Body"为空,但不确定还有什么其他情况。
代码示例:
type Event struct {
Message string `json:"Message"`
}
func unmarshal(message events.SQSMessage) (s3Event, error) {
var e Event
err := json.Unmarshal([]byte(message.Body), &e)
if err != nil {
return s3Event, err
}
var s3Event events.S3Event
err = json.Unmarshal([]byte(e.Message), &sqsEvent)
if err != nil {
return s3Event, err
}
return s3Event, nil
}
感谢任何建议。
英文:
What could be a unit test case for the s3/sqs event when unmarshalling json to struck in Go?
One option that comes to mind is if the "Body" is empty, but not sure what else could it be.
Code example:
type Event struct {
Message string `json:"Message"`
}
func unmarshal(message events.SQSMessage) (s3Event, error) {
var e Event
err := json.Unmarshal([]byte(message.Body), &e)
if err != nil {
return s3Event, err
}
var s3Event events.S3Event
err = json.Unmarshal([]byte(e.Message), &sqsEvent)
if err != nil {
return s3Event, err
}
return s3Event, nil
}
Would appreciate any advice.
答案1
得分: 1
前提:我不确定我是否完全理解了你的问题。此外,代码存在一些问题,导致我很难弄清楚发生了什么。话虽如此,我将尝试通过提供一段可工作的软件代码(并不是非常有用)以及一段用于测试它的软件代码来帮助你。也许,这可以帮助你弄清楚问题所在。
unmarshal.go
文件
package unmarshaltest
import (
"encoding/json"
"fmt"
"github.com/aws/aws-lambda-go/events"
)
type Event struct {
Message string `json:"body"`
}
func Unmarshal(message events.SQSMessage) (string, error) {
rawBytes, _ := json.Marshal(message)
var e Event
json.Unmarshal(rawBytes, &e)
if e.Message == "" {
return "", fmt.Errorf("err while unmarshaling")
}
return e.Message, nil
}
我修复的一件事,并且你应该注意如何命名你的函数。如果你将函数命名为小写的 unmarshal
,这意味着该函数不应从该包中导出(它是私有的)。所以我将名称更改为大写的 U
,因为我猜你想测试这个函数。
unmarshal_test.go
文件
package unmarshaltest
import (
"encoding/json"
"testing"
"github.com/aws/aws-lambda-go/events"
"github.com/stretchr/testify/assert"
)
func TestUnmarshal(t *testing.T) {
t.Run("Unmarshal_NotEmpty_Message", func(t *testing.T) {
var sqsMsg events.SQSMessage
sqsEventRaw := `{ "messageId": "19dd0b57-b21e-4ac1-bd88-01bbb068cb78", "receiptHandle": "MessageReceiptHandle", "body": "My own event payload!", "attributes": { "ApproximateReceiveCount": "1", "SentTimestamp": "1523232000000", "SenderId": "123456789012", "ApproximateFirstReceiveTimestamp": "1523232000001" }, "messageAttributes": {}, "md5OfBody": "4d1d0024b51659ad8c3725f9ba7e2471", "eventSource": "aws:sqs", "eventSourceARN": "arn:aws:sqs:us-east-1:123456789012:MyQueue", "awsRegion": "us-east-1" }`
json.Unmarshal([]byte(sqsEventRaw), &sqsMsg)
res, err := Unmarshal(sqsMsg)
assert.Equal(t, "My own event payload!", res)
assert.Nil(t, err)
})
t.Run("Unmarshal_Empty_Message", func(t *testing.T) {
res, err := Unmarshal(events.SQSMessage{})
assert.Equal(t, "", res)
assert.NotNil(t, err)
})
}
在这里,你可以找到一段简单的代码,用于测试我们的代码可能采取的两种执行流程。你还应该注意如何编写代码。很难将对 json.Unmarshal
函数的调用与模拟调用交换,因为它被硬编码到代码中。如果你希望能够模拟这个函数,你应该在生产代码中依赖接口,并在测试期间用模拟对象替换它们。
如果这解释清楚了一些问题,并且你需要其他帮助,请告诉我!
英文:
Premise: I'm not sure if I've fully understood your question. Furthermore, the code has some issues that cause me hard-time to figure out what's going on. With that being said, I'll try to help you by providing a piece of working software (it's not very useful) together with a piece of software written just to test it. Maybe, this can help you in figuring out your issue.
unmarshal.go
file
package unmarshaltest
import (
"encoding/json"
"fmt"
"github.com/aws/aws-lambda-go/events"
)
type Event struct {
Message string `json:"body"`
}
func Unmarshal(message events.SQSMessage) (string, error) {
rawBytes, _ := json.Marshal(message)
var e Event
json.Unmarshal(rawBytes, &e)
if e.Message == "" {
return "", fmt.Errorf("err while unmarshaling")
}
return e.Message, nil
}
One thing I fixed and you should pay attention to is how you name your functions. If you call your function unmarshal
with lowercase u
it means that this function should not be exported from this package (it's private). So I changed the name with the U
as I supposed you wanna test this function.
unmarshal_test.go
file
package unmarshaltest
import (
"encoding/json"
"testing"
"github.com/aws/aws-lambda-go/events"
"github.com/stretchr/testify/assert"
)
func TestUnmarshal(t *testing.T) {
t.Run("Unmarshal_NotEmpty_Message", func(t *testing.T) {
var sqsMsg events.SQSMessage
sqsEventRaw := `{ "messageId": "19dd0b57-b21e-4ac1-bd88-01bbb068cb78", "receiptHandle": "MessageReceiptHandle", "body": "My own event payload!", "attributes": { "ApproximateReceiveCount": "1", "SentTimestamp": "1523232000000", "SenderId": "123456789012", "ApproximateFirstReceiveTimestamp": "1523232000001" }, "messageAttributes": {}, "md5OfBody": "4d1d0024b51659ad8c3725f9ba7e2471", "eventSource": "aws:sqs", "eventSourceARN": "arn:aws:sqs:us-east-1:123456789012:MyQueue", "awsRegion": "us-east-1" }`
json.Unmarshal([]byte(sqsEventRaw), &sqsMsg)
res, err := Unmarshal(sqsMsg)
assert.Equal(t, "My own event payload!", res)
assert.Nil(t, err)
})
t.Run("Unmarshal_Empty_Message", func(t *testing.T) {
res, err := Unmarshal(events.SQSMessage{})
assert.Equal(t, "", res)
assert.NotNil(t, err)
})
}
Here you can find a simple piece of code that is used to test the two possible execution flows that our code might take.
You should also pay attention to how you write the code. It's very hard to swap the invocation to the json.Unmarshal
function with a mock as it's hard-coded into the code. If your wish is to be able to mock out this function, you should rely on interfaces in your production code and replace them with mocks during tests.
Let me know if this clarifies something and if you need something else!
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论