How to access private static property of a class to use it on testing?

25 Views Asked by At

First of all, I am new in TypeScript and unit testing so this question might be simple for you.

I'm trying to unit test the code below using sinon. I want to test if MyService.channel acknowledged the provided message or not for consumeFunc1 function. But in my test I could not find any way to reach the channel property. What am I missing?

Also I have no option to change the code.

import amqp from 'amqplib'
import logger from '../logger'
import { msgModel } from '../msg.models'
import infoService from '../infoService'

class MyService {
    private static instance: MyService
    private static channel: amqp.Channel

    static getInstance() {
        if (!MyService.instance) {
            MyService.instance = new MyService()
        }
        return MyService.instance
    }

    async init() {
        try {
            const connection = await amqp.connect('amqp://localhost:6789')
            MyService.channel = await connection.createChannel()

            await MyService.channel.assertQueue('queue1')

            MyService.channel.consume('queue1', (msg) => this.consumeFunc1(msg))

            logger.info('MyService started!')
        } catch (error) {
            logger.error(error)
        }
    }

    async consumeFunc1(msg: amqp.ConsumeMessage) {
        if (msg) {
            const msg: msgModel = JSON.parse(msg.content.toString())

            infoService
                .getMeInfo(msg)
                .then((result) => {
                    if (result) {
                        MyService.channel.ack(msg)
                    }
                })
                .catch((error) => {
                    logger.error(error)
                })
        }
    }
}

export default MyService.getInstance()

If I can access to channel, my test would be something like;

it('should acknowledge exampleMsg successfully', async () => {
    const exampleMsg = 'something'

    const channelStub = sandbox.stub(MyService.channel, 'ack')
    await MyService.consumeFunc1(exampleMsg)

    expect(channelStub.calledOnce).toBe(true)
    assert.calledWith(channelStub, exampleMsg)
})

I'm new to testing and all that so also if you have any suggestion about testing, I'm open to it too.

1

There are 1 best solutions below

3
WillPaulViz On

When you run MyService.channel.ack(msg), MyService.channel has not been defined yet in consumeFunc1(). You need to run MyService.init() before you make the channelStub.