I'm writing a test for one of my endpoints that invokes a chaincode transaction on hyperledger fabric. For the test, I want to override the invoke
service to mock a transaction so that a new transaction isn't actually registered in fabric each time.
The code looks simple enough, but for some reason contractsSrv.invoke = jest.fn()
doesn't work. The original invoke
is executed each time.
I've seen many other articles stating to use something like jest.mock('./myModule', () => ({ ...jest.requireActual('./myModule'), otherFn: () => {}}))
or with jest.spyOn
. But it wouldn't work either. At best I was able to get the mock function to return "undefined".
But unless I'm missing something, shouldn't a simple override (as shown below) work? All modules should be cached in memory by the time the function reference is replaced to that of the mock function.
I'm using an older version of node: 14.13.1, as it is required by fabric. Therefore, also using an older version of Jest: 26.6.3.
'use strict';
require('dotenv').config();
const request = require('supertest');
const contractsSrv = require('../../../services/contracts.srv');
const config = require('config');
let server;
jest.setTimeout(3000);
describe('/api/contracts', () => {
beforeEach(() => {
server = require('../../../server');
});
afterEach(() => {
server.close();
});
describe('post /', () => {
it('return transaction record and id', async () => {
contractsSrv.invoke = jest.fn().mockResolvedValue({
data: {
response: 'true',
txID: config.get('TX_ID'),
},
});
const res = await request(server)
.post('/api/contracts')
.send({
field1: '001',
field2: '002',
})
.set('api-token', config.get('TOKEN'));
expect(res.status).toBe(200);
});
});
});
I was able to make it work by using a different method. I've removed the function override and did a jest.doMock outside the describe
method.
jest.doMock('../../../services/contracts.srv', () => {
return {
invoke: jest.fn().mockResolvedValue({
data: {
response: 'true',
txID: config.get('TX_ID'),
},
}),
};
});
I still don't know why a simple override wouldn't work. I think it did work with an older version of jest, so I would think that this is related to how jest internally manages modules, but I don't know for sure.