Mocking узла Node, который использует цепочечные вызовы функций с Jest в Node - PullRequest
3 голосов
/ 14 июня 2019

Позвольте мне отметить, что вопрос, похожий на этот, можно найти здесь , но решение принятого ответа не сработало для меня.В том же духе был еще один вопрос, ответ на который предлагал напрямую манипулировать прототипами функции, но он был в равной степени бесполезным.

Я пытаюсь использовать Jest для насмешки этого модуля NPM, называемого "острым".Он берет буфер изображения и выполняет над ним операции обработки / обработки изображения.

Фактическая реализация модуля в моей кодовой базе выглядит следующим образом:

const sharp = require('sharp');

module.exports = class ImageProcessingAdapter {
    async processImageWithDefaultConfiguration(buffer, size, options) {
        return await sharp(buffer)
            .resize(size)
            .jpeg(options)
            .toBuffer();
    }
}

Вы можете видеть, что модуль используетAPI цепочечной функции, означающий, что макет должен иметь каждую функцию, возвращающую this.

Сам модульный тест можно найти здесь:

jest.mock('sharp');
const sharp = require('sharp');

const ImageProcessingAdapter = require('./../../adapters/sharp/ImageProcessingAdapter');

test('Should call module functions with correct arguments', async () => {
    // Mock values
    const buffer = Buffer.from('a buffer');
    const size = { width: 10, height: 10 };
    const options = 'options';

    // SUT
    await new ImageProcessingAdapter().processImageWithDefaultConfiguration(buffer, size, options);

    // Assertions
    expect(sharp).toHaveBeenCalledWith(buffer);
    expect(sharp().resize).toHaveBeenCalledWith(size);
    expect(sharp().jpeg).toHaveBeenCalledWith(options);
});

Ниже приведены мои попытки насмешки:

Попытка Один

// __mocks__/sharp.js
module.exports = jest.genMockFromModule('sharp');

Результат

Error: Maximum Call Stack Size Exceeded

Попытка Два

// __mocks__/sharp.js
module.exports = jest.fn().mockImplementation(() => ({
    resize: jest.fn().mockReturnThis(),
    jpeg: jest.fn().mockReturnThis(),
    toBuffer:jest.fn().mockReturnThis()
}));

Результат

Expected mock function to have been called with:
      [{"height": 10, "width": 10}]
But it was not called.

Вопрос

Буду признателен за любую помощь в выяснении, как правильно издеваться над этим сторонним модулем, чтобы я мог утверждать, как вызывается макет.

Я пытался использовать sinonи proxyquire, и, похоже, они тоже не справляются с работой.

Воспроизведение

Отдельное воспроизведение этой проблемы можно найти здесь .

Спасибо.

1 Ответ

2 голосов
/ 14 июня 2019

Ваша вторая попытка действительно близка.

Единственная проблема, связанная с этим, заключается в том, что каждый раз, когда sharp вызывается, новый смоделированный объект возвращается с новыми resize, jpeg и toBufferфиктивные функции ...

... что означает, что когда вы тестируете resize следующим образом:

expect(sharp().resize).toHaveBeenCalledWith(size);

... вы фактически тестируете совершенно новую resize фиктивную функциюкоторый не был вызван.

Чтобы исправить это, просто убедитесь, что sharp всегда возвращает один и тот же смоделированный объект:

__ mocks __ / sharp.js

const result = {
  resize: jest.fn().mockReturnThis(),
  jpeg: jest.fn().mockReturnThis(),
  toBuffer: jest.fn().mockReturnThis()
}

module.exports = jest.fn(() => result);
...