当写好chaincode之后, 要怎么测试自己的代码正确呢?有两种方法,一种是直接上peer执行,一种是单元测试
Dev模式测试chaincode
直接上peer执行的话,fabric提供了peer的dev运行模式。好处是节省了chaincode的部署步骤,在dev模式下,可以随时修改chaincode,不用走繁琐的chaincode生命周期流程,比如批准,安装,提交等。
其实还是要走这些流程,但走一次即可,便利之处仅在于可随时修改代码
Dev模式要关闭TLS。因此我们不能采用raft模式部署集群,raft模式必须要求开启TLS。因此我们采用Solo模式部署orderer。~~~闪闪发光的传送门。
启动orderer网络后,来看看dev模式下怎么发布chaincode吧
1. 首先把peer启动为dev模式
peer node start --peer-chaincodedev=true
2. 编译chaincode。这个在本地编译即可,不用进入docker
go mod vendor go build -v -o cc.dev chaincode.go
3. 启动chaincode。这个在本地执行即可,不用进入docker
CORE_CHAINCODE_LOGLEVEL=debug CORE_PEER_TLS_ENABLED=false CORE_CHAINCODE_ID_NAME=mycc:1.0 ./cc.dev -peer.address 127.0.0.1:8150
4. 注册批准chaincode。这些操作如果使用了cli容器,就得在cli中操作
# 批准chaincode定义 peer lifecycle chaincode approveformyorg -o orderer.dev:7050 --channelID channel1 --name mycc --version 1.0 --sequence 1 --package-id mycc:1.0 # 提交chaincode定义 peer lifecycle chaincode commit -o orderer.dev:7050 --channelID channel1 --name mycc --version 1.0 --sequence 1 --peerAddresses peer1.dev:8050
至此,chaincode已经在dev模式下启动了,我们来调用一个试试:
# 调用函数 peer chaincode invoke -o orderer.dev:7050 -C channel1 -n mycc -c '{"function":"InitLedger","Args":[]}' # 查看数据 peer chaincode query -C channel1 -n mycc -c '{"Args":["GetAllAssets"]}'
但要注意的是,在dev模式下的chaincode, Application是无法调用的,会报chaincode没有安装的错误,仔细想想,我们确实也没有执行install动作。因此,和Application联调的时候,老老实实的走正规流程发布chaincode吧
chaincode的单元测试
单元测试也是测试代码非常重要的步骤。chaincode的单元测试采用的是mock手段,即模拟的逻辑来替代执行合约的PutState,GetState等读写行为。因此,单元测试并不能检验chaincode的链上读写功能。单元测试的主要目的,是测试chaincode的业务逻辑是否完整。
chaincode单元测试的例子:~~~闪闪发光的传送门
mock的引入和使用:
import ( ... "github.com/hyperledger/fabric-samples/asset-transfer-basic/chaincode-go/chaincode/mocks" ) func TestCreateAsset(t *testing.T) { //设置mock chaincodeStub := &mocks.ChaincodeStub{} transactionContext := &mocks.TransactionContext{} transactionContext.GetStubReturns(chaincodeStub) assetTransfer := chaincode.SmartContract{} err := assetTransfer.CreateAsset(transactionContext, "", "", 0, "", 0) require.NoError(t, err) //预先设置GetState的值和返回错误,下一条指令assetTransfer.CreateAsset调用的时候,就会返回 //本处设置的值,模拟链上的数据读写,这是mock目的所在 chaincodeStub.GetStateReturns([]byte{}, nil) err = assetTransfer.CreateAsset(transactionContext, "asset1", "", 0, "", 0) require.EqualError(t, err, "the asset asset1 already exists") chaincodeStub.GetStateReturns(nil, fmt.Errorf("unable to retrieve asset")) err = assetTransfer.CreateAsset(transactionContext, "asset1", "", 0, "", 0) require.EqualError(t, err, "failed to read from world state: unable to retrieve asset") }
回复 agodelo 取消回复