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

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

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

问题

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

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

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

英文:

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

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

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>的主体作为示例:

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

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

英文:

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

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

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

答案2

得分: 1

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

package main

import (
	"encoding/json"
	"fmt"
	"strings"
	"testing"
)

type Message struct {
	Name string
}

func TestDecodeFail(t *testing.T) {
	for _, tc := range []struct {
		in   string
		desc string
		out  any
	}{
		{`{Name: "Bobby"}`, "key without quotes", &Message{}},
		{`{"Name": "Foo"a}`, "extra character", &Message{}},
		{`{"Name": "Foo"}`, "bad destination", &struct{ Name int64 }{}},
		{`{"Name": "Foo\u001a"}`, "invalid character", &Message{}},
		{`{"Name": "Foo"}`, "unmarshal to nil", (*Message)(nil)},
	} {
		err := decode(tc.in, tc.out)
		if err != nil {
			fmt.Printf("%s -> %s, %T\n", tc.desc, err.Error(), err)
		}
	}
}

func decode(in string, out any) error {
	return json.NewDecoder(strings.NewReader(in)).Decode(out)
}

输出:

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

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

package main

import (
	&quot;encoding/json&quot;
	&quot;fmt&quot;
	&quot;strings&quot;
	&quot;testing&quot;
)

type Message struct {
	Name string
}

func TestDecodeFail(t *testing.T) {
	for _, tc := range []struct {
		in   string
		desc string
		out  any
	}{
		{`{Name: &quot;Bobby&quot;}`, &quot;key without quotes&quot;, &amp;Message{}},
		{`{&quot;Name&quot;: &quot;Foo&quot;a}`, &quot;extra character&quot;, &amp;Message{}},
		{`{&quot;Name&quot;: &quot;Foo&quot;}`, &quot;bad destination&quot;, &amp;struct{ Name int64 }{}},
		{`{&quot;Name&quot;: &quot;Foo` + &quot;\u001a&quot; + `&quot;}`, &quot;invalid character&quot;, &amp;Message{}},
        {`{&quot;Name&quot;: &quot;Foo&quot;}`, &quot;unmarshal to nil&quot;, (*Message)(nil)},
	} {
		err := decode(tc.in, tc.out)
		if err != nil {
			fmt.Printf(&quot;%s -&gt; %s, %T\n&quot;, tc.desc, err.Error(), err)
		}
	}
}

func decode(in string, out any) error {
	return json.NewDecoder(strings.NewReader(in)).Decode(out)
}

Outputs:

key without quotes -&gt; invalid character &#39;N&#39; looking for beginning of object key string, *json.SyntaxError
extra character -&gt; invalid character &#39;a&#39; after object key:value pair, *json.SyntaxError
bad destination -&gt; json: cannot unmarshal string into Go struct field .Name of type int64, *json.UnmarshalTypeError
invalid character -&gt; invalid character &#39;\x1a&#39; in string literal, *json.SyntaxError
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:

确定