Как заглушить функцию модуля, которая вызывается из другой функции - PullRequest
2 голосов
/ 06 июля 2019

Мой module.ts файл имеет 2 функции:

export async function foo() {
    var barVal = await bar();
    doSomethingWithBarVal(barVal);
}

export async function bar(): Bar {
    return await somethingAsync();
}

В моих тестах я хочу stub bar () и вернуть mock для Bar (возвращаемое значение bar())

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

var module = require('module.ts');
var myStub = sinon.stub(module, 'bar').resolves(myMock);
await foo();
expect(myStub.calledOnce);

Однако, expect всегда терпит неудачу и вызывается 'real' bar().
Если я звоню bar() непосредственно из моего теста, тогда заглушка называется , но я хочу проверить весь поток.

1 Ответ

2 голосов
/ 06 июля 2019

Проблема с вашим подходом заключается в том, что вы заглушаете объект модуля (exports, поскольку вы используете в своем тесте commonjs require), в то время как ваша функция foo использует bar, доступную в области видимости модуля.

Чтобы исправить это, у вас есть несколько вариантов здесь.

1.Быстрый и грязный

Использование exports.bar вместо bar в foo

export async function foo() {
    var barVal = await exports.bar();
    doSomethingWithBarVal(barVal);
}

Этот подход на самом деле является хаком, использующим тот факт, что ваш модуль будет перенесен в формат commonjs,Что может быть неверно когда-нибудь, но пока работает.

2.Примите статический характер модулей ES

Примите тот факт, что модули ES являются статическими.Сделайте вашу функцию «снова тестируемой», явно указав bar в качестве аргумента

export async function foo(_bar = bar) {
    var barVal = await _bar();
    doSomethingWithBarVal(barVal);
}

// test.js
await foo(mockBarImplementation)

3.Продвинутый

Используйте некоторые реализации IoC/DI.Например typcript-ioc

...