更新时间:2023-03-06 GMT+08:00

链代码调测

对链代码进行调测,主要是使用MockStub进行单元测试。本章中测试的链代码获取方法:登录区块链服务管理控制台,进入“应用案例”,单击“Java示例Demo-Java SDK Demo”中“Chaincode_Java_Local_Demo”的“下载”按钮。

添加依赖

使用mock()方法,需要添加mockito相关依赖。

  • gradle版本:
    在build.gradle文件中的dependencies内添加如下配置依赖,注意不是buildscript内的dependencies:
    testCompile 'org.mockito:mockito-core:2.4.1'
  • maven版本:
    在pom.xml文件中的dependencies(若无则添加)内添加如下配置依赖:
    <dependency>
        <groupId>org.mockito</groupId>
        <artifactId>mockito-core</artifactId>
        <version>2.4.1</version>
    </dependency>

编写测试代码

若创建项目时没有test文件夹,在src下新建文件夹,并如图在Gradle Source Sets里面选择“test\java”,然后创建测试文件:SimpleChaincodeTest.java,如图所示:

图1 创建测试文件
图2 测试文件

SimpleChaincodeTest.java测试代码内容:

import org.hyperledger.fabric.example.SimpleChaincode;
import org.hyperledger.fabric.shim.Chaincode;
import org.hyperledger.fabric.shim.ChaincodeStub;
import org.junit.Assert;
import org.junit.Test;

import java.util.ArrayList;
import java.util.List;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

public final class SimpleChaincodeTest {       

    @Test
    public void initTest() {         
        SimpleChaincode sc = new SimpleChaincode();
        ChaincodeStub stub = mock(ChaincodeStub.class);
        Chaincode.Response resp = sc.init(stub);
        Assert.assertEquals(resp.getStatus(), Chaincode.Response.Status.SUCCESS);
    }

    @Test
    public void insertTest() {
        SimpleChaincode sc = new SimpleChaincode();
        ChaincodeStub stub = mock(ChaincodeStub.class);
        when(stub.getFunction()).thenReturn("insert");
        List<String> args = new ArrayList<>();
        args.add("a");
        args.add("100");
        when(stub.getParameters()).thenReturn(args);
        Chaincode.Response resp = sc.invoke(stub);
        Assert.assertEquals(resp.getStatus(), Chaincode.Response.Status.SUCCESS);
    }

    @Test
    public void insertTooManyArgsTest() {
        SimpleChaincode sc = new SimpleChaincode();
        ChaincodeStub stub = mock(ChaincodeStub.class);
        when(stub.getFunction()).thenReturn("insert");
        List<String> args = new ArrayList<>();
        args.add("a");
        args.add("100");
        args.add("b");
        args.add("100");
        when(stub.getParameters()).thenReturn(args);
        Chaincode.Response resp = sc.invoke(stub);
        Assert.assertEquals(resp.getMessage(), "Incorrect number of arguments. Expecting 2");
    }

    @Test
    public void queryTest() {
        SimpleChaincode sc = new SimpleChaincode();
        ChaincodeStub stub = mock(ChaincodeStub.class);
        when(stub.getFunction()).thenReturn("query");
        List<String> args = new ArrayList<>();
        args.add("a");
        when(stub.getParameters()).thenReturn(args);
        when(stub.getStringState("a")).thenReturn("100");
        Chaincode.Response resp = sc.invoke(stub);
        Assert.assertEquals(resp.getMessage(), "100");
    }

    @Test
    public void queryNoExistTest() {
        SimpleChaincode sc = new SimpleChaincode();
        ChaincodeStub stub = mock(ChaincodeStub.class);
        when(stub.getFunction()).thenReturn("query");
        List<String> args = new ArrayList<>();
        args.add("a");
        when(stub.getParameters()).thenReturn(args);
        when(stub.getStringState("a")).thenReturn(null);
        Chaincode.Response resp = sc.invoke(stub);
        Assert.assertEquals(resp.getMessage(), "{\"Error\":\"Null val for a\"}");
    }
}

执行调测

在SimpleChaincodeTest.java中,单击SimpleChaincodeTest方法前的“Run Test”按钮,执行测试。

图3 执行测试

执行成功如图所示,表示链代码调测无问题:

图4 执行成功

执行失败示例如图所示,请根据失败提示修改链代码或者检查调测代码的逻辑:

图5 执行失败