Как заглушить постоянные функции при использовании ES-модулей с sinon.js? - PullRequest
0 голосов
/ 22 мая 2018

С помощью ES-модулей мы определяем некоторые экспортируемые функции как const, и это часто стандартная практика.Тем не менее, во время модульного тестирования эти функции не могут быть заглушены, что кажется проблематичным с точки зрения модульного тестирования.Например,

import * as fs from 'fs';

import { bindNodeCallback } from 'rxjs';
import { map } from 'rxjs/operators';

// readFile :: string, string => Observable<string>
export const readFile$ = bindNodeCallback(fs.readFile);

// readJson :: string => Observable<any>
export function readJson(fileName) {
    return readFile$(fileName, 'utf-8')
        .pipe(map((rawFile) => JSON.parse(rawFile)));
}

Теперь, чтобы выполнить юнит-тест readJson, я бы обычно хотел заглушить функцию readFile$.К сожалению, следующий код Sinon не работает:

// Setup data - stubs / mocks
const stub = sinon.stub(myFs, 'readFile$').returns(json$);

Поскольку Sinon просто меняет ссылку myFs.readFile$, оригинал const по-прежнему указывает на исходную функцию, которая в свою очередь вызывается функцией readJson.

Любое предложение - как я могу действительно заглушить / смоделировать постоянную функцию в одном модуле?

1 Ответ

0 голосов
/ 22 мая 2018

const - постоянное значение, его нельзя изменить с помощью «нормального» кода.К сожалению sinon не волшебство.Вам нужно использовать свой код, чтобы разрешить изменение константного значения.

Предполагая, что вы используете babel для переноса, вы можете использовать babel-plugin-rewire.

После добавления его в ваш babelконфиг вы сможете сделать следующую инъекцию в свой тестовый код

import { default as readJson, __RewireAPI__ as rewire } from './path/to/readJson.js'

const stub = sinon.stub(myFs, 'readFile$').returns(json$)
rewire.__set__('readFile$', stub)

// readJson() would now call provided stub
...