首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

对使用 Go 为 Hyperledger Fabric v0.6 编写的区块链链代码进行单元测试(4)

对使用 Go 为 Hyperledger Fabric v0.6 编写的区块链链代码进行单元测试(4)

清单 11. 重构 sample_chaincode.js 中的 CreateLoanApplication                    代码
1
2
3
4
5
6
7
8
9
func CreateLoanApplication(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) {
    fmt.Println("Entering CreateLoanApplication")
    if len(args) < 2 {
     fmt.Println("Invalid number of args")
     return nil, errors.New("Expected atleast two arguments for loan application creation")
    }

    return nil, nil
}




再次运行测试。测试将会通过。
1 Entering TestCreateLoanApplicationValidation2
2 2017/03/06 12:07:34 MockStub( mockStub &{} )
3 Entering CreateLoanApplication
4 PASS




在我们的下一个测试中,需要验证贷款申请是否已实际创建并写入区块链。将以下测试添加到测试文件中:
清单 12. 验证贷款申请是否已创建并写入区块链中的测试
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
func TestCreateLoanApplicationValidation3(t *testing.T) {
    fmt.Println("Entering TestCreateLoanApplicationValidation3")
    attributes := make(map[string][]byte)
    stub := shim.NewCustomMockStub("mockStub", new(SampleChaincode), attributes)
    if stub == nil {
        t.Fatalf("MockStub creation failed")
    }

    stub.MockTransactionStart("t123")
    CreateLoanApplication(stub, []string{loanApplicationID, loanApplication})
    stub.MockTransactionEnd("t123")

    var la LoanApplication
    bytes, err := stub.GetState(loanApplicationID)
    if err != nil {
        t.Fatalf("Could not fetch loan application with ID " + loanApplicationID)
    }
    err = json.Unmarshal(bytes, &la)
    if err != nil {
        t.Fatalf("Could not unmarshal loan application with ID " + loanApplicationID)
    }
    var errors = []string{}
    var loanApplicationInput LoanApplication
    err = json.Unmarshal([]byte(loanApplication), &loanApplicationInput)
    if la.ID != loanApplicationInput.ID {
        errors = append(errors, "Loan Application ID does not match")
    }
    if la.PropertyId != loanApplicationInput.PropertyId {
        errors = append(errors, "Loan Application PropertyId does not match")
    }
    if la.PersonalInfo.Firstname != loanApplicationInput.PersonalInfo.Firstname {
        errors = append(errors, "Loan Application PersonalInfo.Firstname does not match")
    }
    //Can be extended for all fields
    if len(errors) > 0 {
        t.Fatalf("Mismatch between input and stored Loan Application")
        for j := 0; j < len(errors); j++ {
            fmt.Println(errors[j])
        }
    }
}




第 1-12 行在设置方面与之前的测试一致。在第 14 行,测试尝试检索贷款申请对象,该对象应该已在成功完成第 10 行中调用的                CreateLoanApplication 方法时创建。
stub.GetState(loanApplicationID) 检索与键对应的字节数组值,在本例中该键为来自账本的贷款申请 ID。
在第 18 行,测试尝试将检索的字节数组分解为可以操作和读取的 LoanApplication 结构。
接下来,测试将检索的贷款申请与 CreateLoanApplication                方法的原始输入进行比较,以确保贷款申请和正确的值一起持久保存在账本上。我提供了一些比较某些字段的测试。也可以扩展这些测试来包含其他字段。
备注:此测试跳过了输入模式验证,直接测试贷款申请在账本上的成功持久化。理想情况下,CreateLoanApplication                方法中应包含某种形式的输入模式验证并进行测试,但是,为了确保本教程简洁且可管理,我跳过了这部分内容。
运行测试。跟预期一样,它将失败并抛出以下错误:
1 2017/03/06 18:34:38 MockStub mockStub Getting la1 ()
2 --- FAIL: TestCreateLoanApplicationValidation3 (0.00s)
3         sample_chaincode_test.go:82 Could not unmarshal loan application with ID la1
4 FAIL
5 exit status 1




现在,将以下代码添加到 CreateLoanApplication 方法中,这段代码会将输入贷款申请存储到账本上。
清单 13. 将输入贷款申请存储到账本的代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
func CreateLoanApplication(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) {
    fmt.Println("Entering CreateLoanApplication")

    if len(args) < 2 {
        fmt.Println("Invalid number of args")
        return nil, errors.New("Expected atleast two arguments for loan application creation")
    }

    var loanApplicationId = args[0]
    var loanApplicationInput = args[1]
    //TODO: Include schema validation here

    err := stub.PutState(loanApplicationId, []byte(loanApplicationInput))
    if err != nil {
        fmt.Println("Could not save loan application to ledger", err)
        return nil, err
    }

    fmt.Println("Successfully saved loan application")
    return []byte(loanApplicationInput), nil

}




第 9 和第 10 行从参数中检索 loanApplicationId 和 loanApplicationInput JSON                字符串。之前已经提到过,随后将执行模式验证。
第 13 行使用 stub.PutState 方法将贷款申请存储为键/值对。在转换为字节数组后,贷款申请 ID 被存储为键,贷款申请 JSON                字符串被存储为值。
再次运行 TestCreateLoanApplicationValidation3                测试。测试将会通过。我们已根据最初的要求,完成了 CreateLoanApplication 方法的单元测试和开发。
返回列表