Hyperledger织物链码使用开玩笑模拟

发布于 2025-02-04 14:32:36 字数 3559 浏览 4 评论 0 原文

我正在尝试使用开玩笑将单元测试添加到我的链代码。 From the sample repo

到目前为止,我一直在尝试:

const { ChaincodeStub } = require('fabric-shim');

const MyContract = require('./myContract');

describe('Asset Transfer Basic Tests', () => {
    let transactionContext;
    let mockChaincode;
    let asset;

    beforeEach(() => {
        transactionContext = new Context();

        mockChaincode = ChaincodeStub;

        jest.mock('fabric-shim', () => ({
            ChaincodeStub: jest.fn().mockImplementation(() => ({
                deleteState: jest.fn().mockImplementation(async (key) => {
                    if (mockChaincode.states) {
                        delete mockChaincode.states[key];
                    }
                    return Promise.resolve(key);
                }),
                getState: jest.fn().mockImplementation(async (key) => {
                    let ret;
                    if (mockChaincode.states) {
                        ret = mockChaincode.states[key];
                    }
                    return Promise.resolve(ret);
                }),
                getStateByRange: jest.fn().mockImplementation(async () => {
                    function* internalGetStateByRange() {
                        if (mockChaincode.states) {
                            // Shallow copy
                            const copied = { ...mockChaincode.states };

                            for (const key in copied) {
                                yield { value: copied[key] };
                            }
                        }
                    }

                    return Promise.resolve(internalGetStateByRange());
                }),
                putState: jest.fn().mockImplementation((key, value) => {
                    if (!mockChaincode.states) {
                        mockChaincode.states = {};
                    }
                    mockChaincode.states[key] = value;
                }),
            })),
        }));

        transactionContext.setChaincodeStub(mockChaincode);

        asset = {
            birthDay: '1966-05-31T00:00:00.000Z',
            firstName: 'Federico',
            gender: 'male',
            id: '09c2f565-9923-4b78-bd1c-ff635a70a880',
            lastName: 'Villegas',
        };
    });

    describe('Test InitLedger', (done) => {
        it('should return error on InitLedger', async () => {
            mockChaincode.putState.rejects('failed inserting key');
            const myContract = new MyContract();
            try {
                await myContract.initLedger(transactionContext);
                done.fail('initLedger should have failed');
            } catch (err) {
                expect(err.name).toBe('failed inserting key');
            }
        });

        it('should return success on InitLedger', async () => {
            const myContract = new MyContract();
            await myContract.initLedger(transactionContext);
            const ret = JSON.parse(
                (
                    await mockChaincode.getState(
                        '09c2f565-9923-4b78-bd1c-ff635a70a880',
                    )
                ).toString(),
            );
            expect(ret).toEqual({ ...asset, docType: 'user' });
        });
    });
});

但是到目前为止,我收到的是以下错误: typeError:ctx.stub.putstate不是函数

可能缺少那里的东西。

还有一些简单的东西,例如 sinon jest 中提供的

I am trying to add unit tests to my chaincode using Jest. From the sample repo here, it is using Sinon to handle the mocking of ChaincodeStub using createStubInstance. I am looking to remove Sinon dependency and handle the mocking part using Jest.

So far I have been trying:

const { ChaincodeStub } = require('fabric-shim');

const MyContract = require('./myContract');

describe('Asset Transfer Basic Tests', () => {
    let transactionContext;
    let mockChaincode;
    let asset;

    beforeEach(() => {
        transactionContext = new Context();

        mockChaincode = ChaincodeStub;

        jest.mock('fabric-shim', () => ({
            ChaincodeStub: jest.fn().mockImplementation(() => ({
                deleteState: jest.fn().mockImplementation(async (key) => {
                    if (mockChaincode.states) {
                        delete mockChaincode.states[key];
                    }
                    return Promise.resolve(key);
                }),
                getState: jest.fn().mockImplementation(async (key) => {
                    let ret;
                    if (mockChaincode.states) {
                        ret = mockChaincode.states[key];
                    }
                    return Promise.resolve(ret);
                }),
                getStateByRange: jest.fn().mockImplementation(async () => {
                    function* internalGetStateByRange() {
                        if (mockChaincode.states) {
                            // Shallow copy
                            const copied = { ...mockChaincode.states };

                            for (const key in copied) {
                                yield { value: copied[key] };
                            }
                        }
                    }

                    return Promise.resolve(internalGetStateByRange());
                }),
                putState: jest.fn().mockImplementation((key, value) => {
                    if (!mockChaincode.states) {
                        mockChaincode.states = {};
                    }
                    mockChaincode.states[key] = value;
                }),
            })),
        }));

        transactionContext.setChaincodeStub(mockChaincode);

        asset = {
            birthDay: '1966-05-31T00:00:00.000Z',
            firstName: 'Federico',
            gender: 'male',
            id: '09c2f565-9923-4b78-bd1c-ff635a70a880',
            lastName: 'Villegas',
        };
    });

    describe('Test InitLedger', (done) => {
        it('should return error on InitLedger', async () => {
            mockChaincode.putState.rejects('failed inserting key');
            const myContract = new MyContract();
            try {
                await myContract.initLedger(transactionContext);
                done.fail('initLedger should have failed');
            } catch (err) {
                expect(err.name).toBe('failed inserting key');
            }
        });

        it('should return success on InitLedger', async () => {
            const myContract = new MyContract();
            await myContract.initLedger(transactionContext);
            const ret = JSON.parse(
                (
                    await mockChaincode.getState(
                        '09c2f565-9923-4b78-bd1c-ff635a70a880',
                    )
                ).toString(),
            );
            expect(ret).toEqual({ ...asset, docType: 'user' });
        });
    });
});

but so far what I am getting is the following error: TypeError: ctx.stub.putState is not a function.

Might be missing something there.

Is there also something simpler like the createStubInstance provided by Sinon in Jest?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

美人迟暮 2025-02-11 14:32:36

查看@TSN在评论中发送的链接后,我使用以下方法解决了它:

jest.doMock('fabric-shim');

const { ChaincodeStub } = require('fabric-shim');

const MyContract = require('./myContract');

describe('Asset Transfer Basic Tests', () => {
    let transactionContext;
    let chaincodeStub;
    let asset;

    beforeEach(() => {
        transactionContext = new Context();

        chaincodeStub = new ChaincodeStub();
        transactionContext.setChaincodeStub(chaincodeStub);

        chaincodeStub.putState = jest.fn((key, value) => {
            if (!chaincodeStub.states) {
                chaincodeStub.states = {};
            }
            chaincodeStub.states[key] = value;
        });

        chaincodeStub.getState = jest.fn(async (key) => {
            let ret;
            if (chaincodeStub.states) {
                ret = chaincodeStub.states[key];
            }
            return Promise.resolve(ret);
        });

        chaincodeStub.deleteState = jest.fn(async (key) => {
            if (chaincodeStub.states) {
                delete chaincodeStub.states[key];
            }
            return Promise.resolve(key);
        });

        chaincodeStub.getStateByRange = jest.fn(async () => {
            function* internalGetStateByRange() {
                if (chaincodeStub.states) {
                    // Shallow copy
                    const copied = { ...chaincodeStub.states };

                    for (const key in copied) {
                        yield { value: copied[key] };
                    }
                }
            }

            return Promise.resolve(internalGetStateByRange());
        });

        asset = {
            birthDay: '1966-05-31T00:00:00.000Z',
            firstName: 'Federico',
            gender: 'male',
            id: '09c2f565-9923-4b78-bd1c-ff635a70a880',
            lastName: 'Villegas',
        };
    });

    describe('Test initLedger', (done) => {
        it('should return error on initLedger', async () => {
            chaincodeStub.putState = () =>
                Promise.reject(new Error('failed inserting key'));
            const myContract = new MyContract();
            try {
                await myContract.initLedger(transactionContext);
                done.fail('initLedger should have failed');
            } catch (err) {
                expect(err.message).toBe('failed inserting key');
            }
        });

        it('should return success on initLedger', async () => {
            const myContract = new MyContract();
            await myContract.initLedger(transactionContext);
            const ret = JSON.parse(
                (
                    await chaincodeStub.getState(
                        '09c2f565-9923-4b78-bd1c-ff635a70a880',
                    )
                ).toString(),
            );
            expect(ret).toEqual({ ...asset, docType: 'user' });
        });
    });
});

After looking into the link sent by @TSN in the comment, I solved it using the following approach:

jest.doMock('fabric-shim');

const { ChaincodeStub } = require('fabric-shim');

const MyContract = require('./myContract');

describe('Asset Transfer Basic Tests', () => {
    let transactionContext;
    let chaincodeStub;
    let asset;

    beforeEach(() => {
        transactionContext = new Context();

        chaincodeStub = new ChaincodeStub();
        transactionContext.setChaincodeStub(chaincodeStub);

        chaincodeStub.putState = jest.fn((key, value) => {
            if (!chaincodeStub.states) {
                chaincodeStub.states = {};
            }
            chaincodeStub.states[key] = value;
        });

        chaincodeStub.getState = jest.fn(async (key) => {
            let ret;
            if (chaincodeStub.states) {
                ret = chaincodeStub.states[key];
            }
            return Promise.resolve(ret);
        });

        chaincodeStub.deleteState = jest.fn(async (key) => {
            if (chaincodeStub.states) {
                delete chaincodeStub.states[key];
            }
            return Promise.resolve(key);
        });

        chaincodeStub.getStateByRange = jest.fn(async () => {
            function* internalGetStateByRange() {
                if (chaincodeStub.states) {
                    // Shallow copy
                    const copied = { ...chaincodeStub.states };

                    for (const key in copied) {
                        yield { value: copied[key] };
                    }
                }
            }

            return Promise.resolve(internalGetStateByRange());
        });

        asset = {
            birthDay: '1966-05-31T00:00:00.000Z',
            firstName: 'Federico',
            gender: 'male',
            id: '09c2f565-9923-4b78-bd1c-ff635a70a880',
            lastName: 'Villegas',
        };
    });

    describe('Test initLedger', (done) => {
        it('should return error on initLedger', async () => {
            chaincodeStub.putState = () =>
                Promise.reject(new Error('failed inserting key'));
            const myContract = new MyContract();
            try {
                await myContract.initLedger(transactionContext);
                done.fail('initLedger should have failed');
            } catch (err) {
                expect(err.message).toBe('failed inserting key');
            }
        });

        it('should return success on initLedger', async () => {
            const myContract = new MyContract();
            await myContract.initLedger(transactionContext);
            const ret = JSON.parse(
                (
                    await chaincodeStub.getState(
                        '09c2f565-9923-4b78-bd1c-ff635a70a880',
                    )
                ).toString(),
            );
            expect(ret).toEqual({ ...asset, docType: 'user' });
        });
    });
});
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文