为了账号安全,请及时绑定邮箱和手机立即绑定

在golang函数中测试不可达的执行路径

在golang函数中测试不可达的执行路径

Go
肥皂起泡泡 2022-10-10 19:25:02
我正在编写单元测试来涵盖下面结构链代码中的所有执行路径。但我看不到到达 JSON.Marshall 失败路径的方法。如何传递传递给json.Unmarshal但失败的值json.Marshal?func (c *MyContract) CreateAsset(ctx contractapi.TransactionContextInterface, values string) (bool, error) {        doctype := "myAsset"    txData := []byte(values)    docData := new(DocData)    docData.DataType = doctype    // validate json input & map to struct    err := json.Unmarshal(txData, &docData)    if err != nil {        return false, fmt.Errorf("failed docData unmarshalling: %s", err.Error())    }    docKey, _ := createKey(ctx, doctype, []string{docData.Key1, docData.Key2})    exists, err := c.DocExists(ctx, docKey)    if err != nil {        return false, fmt.Errorf("could not read from world state %s", err)    } else if exists {        return false, fmt.Errorf("asset already exists")    }    txBytes, err := json.Marshal(docData)    if err != nil {        return false, fmt.Errorf("failed docData bytes marshalling: %s", err.Error())    }    return true, ctx.GetStub().PutState(docKey, txBytes)}这是我目前的测试:func TestCreateAsset(t *testing.T) {    var err error    ctx, _ := setupStub()    c := new(MyContract)    _, err = c.CreateAsset(ctx, "{")    assert.EqualError(t, err, "failed unmarshalling: unexpected end of JSON input", "testing malformed json")    _, err = c.CreateAsset(ctx, "{\"key1\":\"mis\",\"key2\":\"sing\"}")    assert.EqualError(t, err, "could not read from world state some failure")    _, err = c.CreateAsset(ctx, "{\"key1\":\"001\",\"key2\":\"002\"}")    assert.EqualError(t, err, "asset already exists")}
查看完整描述

1 回答

?
缥缈止盈

TA贡献2041条经验 获得超4个赞

json.Marshal当无法封送数据中的值时,该函数将失败。导致失败的唯一方法是引入一个用于测试的字段并在测试期间输入一个错误的值:


type DocData struct {

    …

    Test       interface{} `json:"test,omitempty"`

}



var induceFailure interface{}



docData.Test = induceFailure

txBytes, err := json.Marshal(docData)

if err != nil {

    return false, fmt.Errorf("failed docData bytes marshalling: %s", err.Error())

}



func TestMarshlFail(t *testing.T) {

    induceFailure = make(chan struct{})

    defer func() {

       induceFailure= nil

    }()

    …

在该行代码上获得测试覆盖率可能不值得麻烦。


与手头的问题无关,这里有一些对您的代码的改进。


包装错误而不是将错误转换为字符串:


return nil, fmt.Errorf("failed docData unmarshalling: %w", err)

因为docData是指针,解组时不需要取值的地址。


err := json.Unmarshal(txData, docData)


查看完整回答
反对 回复 2022-10-10
  • 1 回答
  • 0 关注
  • 73 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信