Quite new to unit testing. I am writing unit tests for my code using Chai+Mocha and Sinon and I am stuck at a point because I am not able to decide whether I should use a Sinon stub or a fake. I have two functions processHash
and processBatch
. processHash
internally calls processBatch
, since I have already written a test case for processBatch
I don't think it makes sense to test it again when I test processHash
So when writing test cases for processHash
my first opinion was to go ahead with a stub and resolve processBatch
manually which I have done in the test case for processBatch
since it interacts with a Redis cache and SQL db internally (third party services). Then I was reading the docs for fakes and it seems fakes are suitable for this use case, thus the confusion about what the use
Here are the functions I am working with:
const processBatch = async (hashKeys, timestamp) => {
// Get data from Redis Hash
const [detailsArr, detailsErr] = await cacheService.getMultipleFieldsFromHash(
'user_details',
hashKeys
);
//DB insertion
const [insertSuccess, insertError] = await dbService.insertLogs(
detailsArr,
timestamp
);
hashKeys = [];
return [true, null];
};
const processHash = async (key, timestamp, currentTimestamp) => {
//get hashKeys from sorted set
const [hashKeys, hashKeysError] = await cacheService.getDataInRange(
key,
0,
-1
);
const batchSize = BATCH_SIZE;
const totalKeys = hashKeys.length;
for (let i = 0; i < totalKeys; i += batchSize) {
const batch = hashKeys.slice(i, i + batchSize);
const [success, error] = await processBatch(batch, timestamp);
}
return [true, null];
};
Test case for processBatch
:
describe('processBatch function', () => {
it('should return success=true if it executes correctly', async () => {
cacheServiceStub = sinon.stub();
dbServiceStub = sinon.stub();
cacheServiceStub.getMultipleFieldsFromHash.resolves([[], null]);
dbServiceStub.insertLogs().resolves([true, null]);
const [success, err] = await processBatch(hashKeys, timestamp);
expect(success).to.be.a('boolean');
expect(success).to.be.equal(true);
expect(err).to.be.null;
});
});
I would go for using a stub, you are just trying to test processHash so that is the priority.
But also I think with testing there is no hard and fast rules either. A fake might be more helpful when you want to add more complexity to your test.
The way I personally frame it is: What am I trying to test? -> Then you go from there and your method of testing should be clear. As opposed to letting your method of testing define your test, testing is just a tool in the end.