对使用 Go 为 Hyperledger Fabric v0.6 编写的区块链链代码进行单元测试(4)
- UID
- 1066743
|
对使用 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 方法的单元测试和开发。 |
|
|
|
|
|