Search code examples
javascriptunit-testingsinonstub

How to properly create unit test for logic inside arrow function


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?


Solution

  • Yes it is doable. There are 2 alternatives:

    1. Stub MassiveJS methods directly.

    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'));
    
    1. Use pg in memory for test.

    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.