如何为json.NewDecoder.Decode编写单元测试失败案例?

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

How to write unit test failure for json.NewDecoder.Decode?

问题

我必须为一个函数编写单元测试,而这个函数使用了json.NewDecoder.Decode

  1. var infos models.RegisterInfos // 带有json字段的结构体
  2. err := json.NewDecoder(r.Body).Decode(&infos)
  3. if err != nil {
  4. // 处理错误
  5. }

在单元测试中(使用testing包),如何模拟json.NewDecoder(r.Body).Decode(&infos)的错误?我尝试查看NewDecoderDecode的源代码,但是我找不到可以在几行代码中生成错误的内容。

英文:

I have to write unit tests for a function and this function uses json.NewDecoder.Decode

  1. var infos models.RegisterInfos // struct with json fields
  2. err := json.NewDecoder(r.Body).Decode(&infos)
  3. if err != nil {
  4. // do something
  5. }

How can I simulate an error in a unit test (using the testing package) for json.NewDecoder(r.Body).Decode(&infos) ? I tried looking in the NewDecoder and Decode source code but I couldn't find anything that can generate an error in just a few lines.

答案1

得分: 1

你可以发送一个类似<invalid json>的主体作为示例:

  1. func main() {
  2. body := "<invalid json>"
  3. var infos RegisterInfos // 带有 JSON 字段的结构体
  4. err := json.NewDecoder(strings.NewReader(body)).Decode(&infos)
  5. if err != nil {
  6. fmt.Println(err)
  7. }
  8. }

请参阅 https://go.dev/play/p/44E99D0eQou

英文:

you could send a body like &lt;invalid json&gt; as example:

  1. func main() {
  2. body := &quot;&lt;invalid json&gt;&quot;
  3. var infos RegisterInfos // struct with json fields
  4. err := json.NewDecoder(strings.NewReader(body)).Decode(&amp;infos)
  5. if err != nil {
  6. fmt.Println(err)
  7. }
  8. }

See https://go.dev/play/p/44E99D0eQou

答案2

得分: 1

将其输入无效输入或解码为无效输出:

  1. package main
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "strings"
  6. "testing"
  7. )
  8. type Message struct {
  9. Name string
  10. }
  11. func TestDecodeFail(t *testing.T) {
  12. for _, tc := range []struct {
  13. in string
  14. desc string
  15. out any
  16. }{
  17. {`{Name: "Bobby"}`, "key without quotes", &Message{}},
  18. {`{"Name": "Foo"a}`, "extra character", &Message{}},
  19. {`{"Name": "Foo"}`, "bad destination", &struct{ Name int64 }{}},
  20. {`{"Name": "Foo\u001a"}`, "invalid character", &Message{}},
  21. {`{"Name": "Foo"}`, "unmarshal to nil", (*Message)(nil)},
  22. } {
  23. err := decode(tc.in, tc.out)
  24. if err != nil {
  25. fmt.Printf("%s -> %s, %T\n", tc.desc, err.Error(), err)
  26. }
  27. }
  28. }
  29. func decode(in string, out any) error {
  30. return json.NewDecoder(strings.NewReader(in)).Decode(out)
  31. }

输出:

  1. key without quotes -> invalid character 'N' looking for beginning of object key string, *json.SyntaxError
  2. extra character -> invalid character 'a' after object key:value pair, *json.SyntaxError
  3. bad destination -> json: cannot unmarshal string into Go struct field .Name of type int64, *json.UnmarshalTypeError
  4. invalid character -> invalid character '\x1a' in string literal, *json.SyntaxError
  5. unmarshal to nil -> json: Unmarshal(nil *main.Message), *json.InvalidUnmarshalError
英文:

Feed it an invalid input, or decode into an invalid output:

  1. package main
  2. import (
  3. &quot;encoding/json&quot;
  4. &quot;fmt&quot;
  5. &quot;strings&quot;
  6. &quot;testing&quot;
  7. )
  8. type Message struct {
  9. Name string
  10. }
  11. func TestDecodeFail(t *testing.T) {
  12. for _, tc := range []struct {
  13. in string
  14. desc string
  15. out any
  16. }{
  17. {`{Name: &quot;Bobby&quot;}`, &quot;key without quotes&quot;, &amp;Message{}},
  18. {`{&quot;Name&quot;: &quot;Foo&quot;a}`, &quot;extra character&quot;, &amp;Message{}},
  19. {`{&quot;Name&quot;: &quot;Foo&quot;}`, &quot;bad destination&quot;, &amp;struct{ Name int64 }{}},
  20. {`{&quot;Name&quot;: &quot;Foo` + &quot;\u001a&quot; + `&quot;}`, &quot;invalid character&quot;, &amp;Message{}},
  21. {`{&quot;Name&quot;: &quot;Foo&quot;}`, &quot;unmarshal to nil&quot;, (*Message)(nil)},
  22. } {
  23. err := decode(tc.in, tc.out)
  24. if err != nil {
  25. fmt.Printf(&quot;%s -&gt; %s, %T\n&quot;, tc.desc, err.Error(), err)
  26. }
  27. }
  28. }
  29. func decode(in string, out any) error {
  30. return json.NewDecoder(strings.NewReader(in)).Decode(out)
  31. }

Outputs:

  1. key without quotes -&gt; invalid character &#39;N&#39; looking for beginning of object key string, *json.SyntaxError
  2. extra character -&gt; invalid character &#39;a&#39; after object key:value pair, *json.SyntaxError
  3. bad destination -&gt; json: cannot unmarshal string into Go struct field .Name of type int64, *json.UnmarshalTypeError
  4. invalid character -&gt; invalid character &#39;\x1a&#39; in string literal, *json.SyntaxError
  5. unmarshal to nil -&gt; json: Unmarshal(nil *main.Message), *json.InvalidUnmarshalError

huangapple
  • 本文由 发表于 2022年11月3日 23:48:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/74305892.html
匿名

发表评论

匿名网友

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

确定