Я пытаюсь выяснить, как тестировать внутренние (то есть не экспортируемые) функции в nodejs (желательно с mocha или jasmine). И я понятия не имею!
Допустим, у меня есть такой модуль:
function exported(i) {
return notExported(i) + 1;
}
function notExported(i) {
return i*2;
}
exports.exported = exported;
И следующий тест (мокко):
var assert = require('assert'),
test = require('../modules/core/test');
describe('test', function(){
describe('#exported(i)', function(){
it('should return (i*2)+1 for any given i', function(){
assert.equal(3, test.exported(1));
assert.equal(5, test.exported(2));
});
});
});
Есть ли способ модульного тестирования notExported
функции без ее фактического экспорта, поскольку она не предназначена для показа?
node.js
unit-testing
jasmine
mocha
xavier.seignard
источник
источник
Ответы:
Модуль rewire - определенно ответ.
Вот мой код для доступа к неэкспортированной функции и ее тестирования с помощью Mocha.
application.js:
test.js:
источник
Cannot find module '../../package' from 'node.js'
. Вы видели это?Хитрость заключается в том, чтобы установить
NODE_ENV
переменную окружения на что-то подобное,test
а затем экспортировать ее условно.Предполагая, что вы не установили глобальный mocha, вы можете иметь Makefile в корневом каталоге вашего приложения, который содержит следующее:
Этот make-файл устанавливает NODE_ENV перед запуском mocha. Затем вы можете запустить свои тесты мокко с
make test
помощью командной строки.Теперь вы можете условно экспортировать свою функцию, которая обычно не экспортируется, только когда выполняются ваши тесты mocha:
Другой ответ предложил использовать модуль vm для оценки файла, но это не работает и выдает ошибку, в которой говорится, что экспорт не определен.
источник
РЕДАКТИРОВАТЬ:
Загрузка модуля с использованием
vm
может вызвать непредвиденное поведение (например,instanceof
оператор больше не работает с объектами, созданными в таком модуле, поскольку глобальные прототипы отличаются от тех, которые используются в модуле, загружаемом обычноrequire
). Я больше не использую описанную ниже технику и вместо этого использую модуль rewire . Это работает чудесно. Вот мой оригинальный ответ:Разработка ответа Сроша ...
Это немного странно, но я написал простой модуль "test_utils.js", который позволит вам делать то, что вы хотите, без условного экспорта в ваших модулях приложения:
Есть еще несколько вещей, которые включены в
module
объект gobal модуля узла, которые также могут потребоватьсяcontext
объект выше, но это минимальный набор, который мне нужен для его работы.Вот пример использования мокко BDD:
источник
rewire
?Работая с Жасмин, я попытался углубиться в решение, предложенное Энтони Мэйфилдом , на основе rewire .
Я реализовал следующую функцию ( Внимание : еще не полностью протестирован, просто предоставлен в качестве возможной стратегии) :
С такой функцией вы могли бы шпионить за методами неэкспортированных объектов и неэкспортированных функций верхнего уровня, следующим образом:
Тогда вы можете установить ожидания следующим образом:
источник
Вы можете создать новый контекст, используя модуль vm, и оценить в нем js-файл, как в repl. тогда у вас есть доступ ко всему, что он заявляет.
источник
Я нашел довольно простой способ, который позволяет вам тестировать, шпионить и высмеивать эти внутренние функции из тестов:
Допустим, у нас есть модуль узла, подобный этому:
Если мы теперь хотим проверить и шпионить и издеваться
myInternalFn
, не экспортируя его в производство , мы должны улучшить этот файл , как это:Теперь вы можете тестировать, шпионить и издеваться
myInternalFn
везде, где вы используете его, аtestable.myInternalFn
в производстве он не экспортируется .источник
Это не рекомендуемая практика, но если вы не можете использовать
rewire
как предложено @Antoine, вы всегда можете просто прочитать файл и использоватьeval()
.Я нашел это полезным при модульном тестировании JS-файлов на стороне клиента для устаревшей системы.
В файлах JS будет установлено множество глобальных переменных
window
без каких-либоrequire(...)
иmodule.exports
заявлений (не было модуля пакетирования как Webpack или Browserify доступны , чтобы удалить эти заявления в любом случае).Вместо рефакторинга всей кодовой базы это позволило нам интегрировать модульные тесты в наш клиентский JS.
источник