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

我正在编写单元测试来涵盖下面结构链代码中的所有执行路径。但我看不到到达 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")


}


肥皂起泡泡
浏览 79回答 1
1回答

缥缈止盈

json.Marshal当无法封送数据中的值时,该函数将失败。导致失败的唯一方法是引入一个用于测试的字段并在测试期间输入一个错误的值:type DocData struct {    …    Test       interface{} `json:"test,omitempty"`}…var induceFailure interface{}…docData.Test = induceFailuretxBytes, 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)
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go