Jest - Проверить, что замоканный метод класса был вызван 1 раз

Пишу unit-тесты с использованием jest. Пытаюсь разобраться, как работают моки. Возьмем пример. Есть следующие классы:

processor.js

const Sender = require("./sender");

class Processor {
    constructor(dataProvider) {
        this._dataProvider = dataProvider;
        this._sender = new Sender();
    }

    async process(clientId) {
        const config = await this._dataProvider.getConfig(clientId);
        if (config === null) {
            return;
        }
        
        await this._sender.sendTo(clientId);
    }
}

module.exports = Processor;

dataProvider.js

class DataProvider {
    
    async getConfig(clientId) {

        // Implementation goes here...
        return {
            id: 1,
            clientId: clientId,
            text: 'hello world!',
        };
    }
}

module.exports = DataProvider;

sender.js

class Sender {
    async sendTo(clientId) {
        console.log(`Data Sended to ${clientId}!`);
    }
}

module.exports = Sender;

Я хочу написать тест для processor.js. Пытаюсь написать тест на "положительное" поведение, вот что я написал:

processor.test.js

setupInitialMocks();

const Processor = require('../modules/processor');
const DataProvider = require('../modules/dataProvider');
const Sender = require('../modules/sender');

describe('processor', () => {
    beforeEach(() => {
        DataProvider.mockClear();
        Sender.mockClear();
    });

    it('should send data', async () => {
        const clientid = 'google';
        const dataProvider = new DataProvider();
        const processor = new Processor(dataProvider);

        await processor.process(clientid);

        const dataProviderInstance = DataProvider.mock.instances[0];
        const getConfigMethod = dataProviderInstance.getConfig;

        const senderMockInstance = Sender.mock.instances[0];
        const sendMethod = senderMockInstance.sendTo;

        expect(getConfigMethod).toHaveBeenCalledTimes(1);
        expect(sendMethod).toHaveBeenCalledTimes(1);
    });
});

function setupInitialMocks() {
    jest.mock('../modules/dataProvider', () => {
        return jest.fn().mockImplementation(() => {
            return {
                getConfig: (clientId) => Promise.resolve({
                    id: 100500,
                    clientId: clientId,
                    text: 'MOCKED hello world!',
                }),
            };
        });
    });

    jest.mock('../modules/sender');
}

Такой тест не работает, вот что показывает при запуске npm run test:

● processor › should send data

expect(received).toHaveBeenCalledTimes(expected)

Matcher error: received value must be a mock or spy function

Received has value: undefined

  24 |         const sendMethod = senderMockInstance.sendTo;
  25 |
> 26 |         expect(getConfigMethod).toHaveBeenCalledTimes(1);
     |                                 ^
  27 |         expect(sendMethod).toHaveBeenCalledTimes(1);
  28 |     });
  29 | });

  at Object.toHaveBeenCalledTimes (jest-sandbox/processor.test.js:26:33)

При этом, если я закомментирую expect(getConfigMethod).toHaveBeenCalledTimes(1);, то второй expect проходит успешно.

Вопрос: как можно исправить данный код, чтобы подменить реализацию getConfig для DataProvider и при этом отследить количество вызовов этого метода?


Ответы (0 шт):