fabric-mock-stub icon indicating copy to clipboard operation
fabric-mock-stub copied to clipboard

fabric-mock-stub problem with creation of chaincodeMockStub instance

Open hnamzian opened this issue 6 years ago • 10 comments

Hi, I'm trying to test my contract created by IBM blockchain platform VSCIDE extension. My contract is written in typescript. Now in order to test my contract I've used the following code:

import { MyContract } from '../src/my-contract';
import { ChaincodeMockStub, Transform } from "@theledger/fabric-mock-stub";
 
// You always need your chaincode so it knows which chaincode to invoke on
const chaincode = new MyContract();
 
describe('Test MyChaincode', () => {
 
    it("Should init without issues", async () => {
        const mockStub = new ChaincodeMockStub("MyMockStub", chaincode);
 
        // Your test code
    });
});

and I get 2 errors. first I get "Unexpected token import", and second there is an error with the below line:

const mockStub = new ChaincodeMockStub("MyMockStub", chaincode);

says "Argument of type "MyContract" is not assignable to parameter of type "ChaincodeInterface" ".

Thanks for help.

hnamzian avatar Feb 16 '19 11:02 hnamzian

Could you show me your contract? Are you using the new wrapper around the shim introduced in 1.4? We do not support this yet. This explains your second issue.

The first issue might be because your testing library (mocha or other) might not be configured correctly to compile this es6 to es5 syntax.

sneljo1 avatar Feb 16 '19 12:02 sneljo1

This is mycontract:

import { Context, Contract } from 'fabric-contract-api';

export class MyContract extends Contract {

    public async instantiate(ctx: Context): Promise<any> {
        console.info('instantiate');
    }

    public async transaction1(ctx: Context, arg1: string): Promise<any> {
        console.info('transaction1', arg1);
    }

    public async transaction2(ctx: Context, arg1: string, arg2: string): Promise<any> {
        console.info('transaction2', arg1, arg2);
    }

}

hnamzian avatar Feb 16 '19 12:02 hnamzian

AH, yes. We do not support the Contract from fabric-contract-api (yet). It has been introduced in 1.4

sneljo1 avatar Feb 16 '19 12:02 sneljo1

Me too! Looking forward for fabric-contract-api support.

hoangedward avatar Apr 08 '19 11:04 hoangedward

+1 looking forward to it. Please can we have any expectation on when :)

bhanuratnakaram avatar Apr 09 '19 13:04 bhanuratnakaram

+1 Agreed.

SamCullin avatar May 06 '19 04:05 SamCullin

I am also trying out new contract-api, and found out that mockstub is not available, found this, and looks like contract-api is not supported, are there any workarounds for this, or any plans to implement it?

hazimdikenli avatar May 28 '19 14:05 hazimdikenli

Is v1.4 has support for contract-api?

jeevan-ghule avatar Nov 28 '19 12:11 jeevan-ghule

Does anyone have found a way to unit test their contracts?

eduardosanzbBCG avatar Jan 19 '20 14:01 eduardosanzbBCG

I know how annoying this is to be unable to test own code, I spent a week searching through the web and found nothing. Eventually, I came up with this workaround to use theLedger MockStub with contract API and it works just fine for me.

import { expect } from 'chai';
import { MyChaincode } from '../src/contract/MyChaincode'; // My Contract implementation
import { ChaincodeMockStub } from '@theledger/fabric-mock-stub';
import shim from 'fabric-shim';

// It's necessary to implement all methods from lovely shim chaincode interface
// to use theLedger MockStub with my Contract implementation
class ChaincodeFromShim extends MyChaincode {
    constructor() {
        super();
    }
    async Init(stub: ChaincodeMockStub): Promise<shim.ChaincodeResponse> {
        return shim.success();
    }
    async Invoke(stub: ChaincodeMockStub): Promise<shim.ChaincodeResponse> {
        const context = this.createContext(); // I implement this method in MyChaincode
        context.stub = stub;

        const args = stub.getFunctionAndParameters();
        const fnc = args.fcn;
        const params = args.params;

        const method = (this as any)[fnc];
        if (!method) {
            console.log(`Method ${method} does not exist`);
            shim.error(Buffer.from('This method does not exist'));
        }

        try {
            const result = await (this as any)[fnc](context, ...params);
            return shim.success(Buffer.from(JSON.stringify(result?result:"")));
        } catch(err) {
            console.log(err);
            return shim.error(Buffer.from(JSON.stringify(err)));
        }
    }
}

const chaincode = new ChaincodeFromShim();

it("Should invoke my contract c1", async () => {
        const mockStub = new ChaincodeMockStub("MyMockStub", chaincode);

        const c1Response = await mockStub.mockInvoke("txID1", ["c1", 'arg1', 'arg2']);
        expect(c1Response.status).to.eql(200);
});

yuuhn avatar May 26 '20 01:05 yuuhn