Я использую мокко для модульного тестирования приложения, написанного для node.js
Интересно, возможно ли модульное тестирование функций, которые не были экспортированы в модуль.
Пример:
У меня есть много таких функций, определенных в foobar.js
function private_foobar1(){
...
}
function private_foobar2(){
...
}
и несколько функций, экспортированных как общедоступные:
exports.public_foobar3 = function(){
...
}
Тестовый пример структурирован следующим образом:
describe("private_foobar1", function() {
it("should do stuff", function(done) {
var stuff = foobar.private_foobar1(filter);
should(stuff).be.ok;
should(stuff).....
Очевидно, это не работает, поскольку private_foobar1
не экспортируется.
Как правильно проводить модульное тестирование частных методов? Есть ли у мокко какие-нибудь встроенные методы для этого?
Ответы:
Если функция не экспортируется модулем, она не может быть вызвана тестовым кодом вне модуля. Это связано с тем, как работает JavaScript, и Mocha не может этого избежать.
В тех немногих случаях, когда я определил, что тестирование частной функции - это правильно, я установил некоторую переменную среды, которую мой модуль проверяет, чтобы определить, запущена ли она в тестовой настройке или нет. Если он работает в тестовой настройке, он экспортирует дополнительные функции, которые я затем могу вызвать во время тестирования.
Слово «окружающая среда» здесь используется в широком смысле. Это может означать проверку
process.env
или что-то еще, что может сообщить модулю «вы сейчас тестируете». Примеры, когда мне приходилось это делать, были в среде RequireJS, и я использовалmodule.config
для этой цели.источник
SyntaxError: 'import' and 'export' may only appear at the top level
import
,export
внутри блока. В конце концов, вы сможете делать такие вещи в ES6 с помощью системного загрузчика. Один из способов обойти это сейчас - использоватьmodule.exports = process.env.NODE_ENV === 'production' ? require('prod.js') : require('dev.js')
и хранить различия кода es6 в этих соответствующих файлах.Проверить перепайку модуль . Он позволяет вам получать (и манипулировать) частные переменные и функции внутри модуля.
Итак, в вашем случае использование будет примерно таким:
источник
Cannot find module '../../package' from 'node.js'
. Кто-нибудь знаком с этим?.ts
,typescript
я бегаю с помощьюts-node
@cluВот действительно хороший рабочий процесс для тестирования ваших частных методов, который объяснил в своем блоге инженер Google Филип Уолтон.
Принцип
_
например,Затем используйте задачу сборки или свою собственную систему сборки (например, grunt-strip-code), чтобы удалить этот блок для производственных сборок.
Ваши тестовые сборки имеют доступ к вашему частному api, а ваши производственные сборки - нет.
отрывок
Напишите свой код так:
И такие твои черновые задачи
Глубже
В более поздней статье объясняется, почему «тестирование частных методов».
источник
Если вы предпочитаете, чтобы это было просто, просто экспортируйте и частные члены, но четко отделенные от общедоступного API некоторым соглашением, например, добавьте к ним префикс
_
или вложите их в один частный объект.источник
Для этой цели я сделал пакет npm, который может вам пригодиться: require-from
В основном вы предоставляете непубличные методы:
примечание:
testExports
может быть любое допустимое имя, за исключениемexports
конечно.И из другого модуля:
источник
requireFrom
с правильными параметрами.) Также, если модуль сtextExports
загруженrequire
вызовом доrequireFrom
его загрузки,requireFrom
вернетсяundefined
. (Я только что это протестировал.) Хотя часто можно контролировать порядок загрузки модулей, это не всегда практично. (Как свидетельствуют некоторые вопросы Mocha по SO.) Это решение также обычно не работает с модулями типа AMD. (Я загружаю модули AMD в Node ежедневно для тестирования.)Я добавил дополнительную функцию, которую назвал Internal (), и оттуда возвращаю все частные функции. Затем эта функция Internal () экспортируется. Пример:
Вы можете вызвать внутренние функции следующим образом:
Мне больше всего нравится это решение, потому что:
источник
Я последовал за ответом @barwin и проверил, как можно выполнять модульные тесты с помощью модуля rewire . Я могу подтвердить, что это решение просто работает.
Модуль должен состоять из двух частей - публичной и частной. Для публичных функций это можно сделать стандартным способом:
Для частного использования:
Чтобы узнать больше о предмете, я создал рабочий пример с полным тестированием модуля, тестирование включает частную и общедоступную области.
Для получения дополнительной информации я рекомендую вам проверить статью ( https://medium.com/@macsikora/how-to-test-private-functions-of-es6-module-fb8c1345b25f ), полностью описывающую тему, она включает примеры кода.
источник
Я знаю, что это не обязательно тот ответ, который вы ищете, но я обнаружил, что в большинстве случаев, если частную функцию стоит протестировать, стоит разместить ее в отдельном файле.
Например, вместо того, чтобы иметь частные методы в том же файле, что и общедоступные, например ...
ЦСИ / вещь / PublicInterface.js
... вы разделите его так:
ЦСИ / вещь / PublicInterface.js
ЦСИ / вещь / внутренний / helper1.js
ЦСИ / вещь / внутренний / helper2.js
Таким образом, вы можете легко проверить
helper1
иhelper2
как есть, без использования Rewire и другой «магии» (который я нашел, есть свои болевые точки во время отладки, или когда вы пытаетесь сделать свой шаг к машинопись, не говоря уже о бедных понятность для новых коллег). И то, что они находятся в подпапке с названиемinternal
или что-то в этом роде, поможет избежать их случайного использования в непредусмотренных местах.PS: Еще одна распространенная проблема с «частными» методов является то , что если вы хотите проверить
publicMethod1
иpublicMethod2
и издеваться хелперов, опять же , вам обычно нужно что - то вроде Rewire , чтобы сделать это. Однако, если они находятся в отдельных файлах, вы можете использовать для этого Proxyquire , который, в отличие от Rewire, не требует каких-либо изменений в процессе сборки, легко читается и отлаживается и хорошо работает даже с TypeScript.источник
Чтобы сделать частные методы доступными для тестирования, я делаю следующее:
источник