英文:
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)的错误?我尝试查看NewDecoder和Decode的源代码,但是我找不到可以在几行代码中生成错误的内容。
英文:
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 <invalid json> as example:
func main() {
	body := "<invalid json>"
	var infos RegisterInfos // struct with json fields
	err := json.NewDecoder(strings.NewReader(body)).Decode(&infos)
	if err != nil {
		fmt.Println(err)
	}
}
答案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 (
	"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)
}
Outputs:
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论