I'm working on an existing NodeJS web service using HapiJS, Hapi Lab for testing along with Sinon. The service connects to a Postgres DB using massiveJs. There's a method implemented by someone else, that doesn't have unit tests. Now I'm reusing this method and I want to implement some unit tests for it. This method executes a massivejs transaction inside of it, persisting to several tables.
async createSomething(payload) {
const { code, member } = payload;
const foundCompany = await this.rawDb.ethnics.tenants.findOne({ code });
if (foundCompany && foundCompany.companyId) {
const { companyId } = foundCompany;
const { foreignId } = member;
return await this.rawDb.withTransaction(async (tx) => {
const foundMember = await tx.ethnics.members.findOne({ foreign_id: foreignId, company_id: companyId });
if (!foundMember) {
//some business logic...
const newMember = await tx.ethnics.members.insert(member);
//more business logic persisting to other tables...
return newMember;
}
});
}
}
Problem is, I don't know how to stub stuff only inside the arrow function, without stubbing the entire arrow function. I just want to stub the calls of tx. I also don't want to use a database but stub the rawDb property. Is that doable from unit testing perspective?
Yes it is doable. There are 2 alternatives:
Example to stub massive method findOne:
const massive = require('massive');
const sinon = require('sinon');
// Stub massive.Readable class method findOne.
// You need to find where is the real method findOne and stub it.
const stub = sinon.stub(massive.Readable, 'findOne');
// You can resolve it.
stub.resolves();
// Or you can throw it.
stub.throws(new Error('xxx'));
Just for testing purpose, you can use module like: test-pg-pool or pg-mem. Before testing, start the test pg and after the test finish, destroy it.