У меня есть модуль AMD, который я хочу протестировать, но я хочу имитировать его зависимости вместо загрузки фактических зависимостей. Я использую requirejs, и код моего модуля выглядит примерно так:
define(['hurp', 'durp'], function(Hurp, Durp) {
return {
foo: function () {
console.log(Hurp.beans)
},
bar: function () {
console.log(Durp.beans)
}
}
}
Как я могу имитировать hurp
и durp
эффективно тестировать модули?
javascript
unit-testing
mocking
requirejs
jergason
источник
источник
define
функцию. Однако есть несколько разных вариантов. Я отправлю ответ в надежде, что это будет полезно.Ответы:
Итак, после прочтения этого поста я придумал решение, использующее функцию конфигурации requirejs для создания нового контекста для вашего теста, где вы можете просто имитировать свои зависимости:
Таким образом, он создает новый контекст, в котором определения
Hurp
иDurp
будут установлены объектами, которые вы передали в функцию. Math.random для имени может быть немного грязным, но он работает. Потому что, если у вас будет куча тестов, вам нужно создать новый контекст для каждого пакета, чтобы предотвратить повторное использование ваших макетов, или для загрузки макетов, когда вам нужен настоящий модуль requirejs.В вашем случае это будет выглядеть так:
Так что я какое-то время использую этот подход в производстве, и он действительно надежен.
источник
createContext
функции. Итак, в вашем случае, если вы перейдете только{hurp: 'hurp'}
к функции,durp
файл будет загружен как обычная зависимость.Вы можете попробовать новую библиотеку Squire.js
из документов:
Squire.js - это инжектор зависимостей для пользователей Require.js, который упрощает имитацию зависимостей!
источник
Я нашел три разных решения этой проблемы, ни одно из них не было приятным.
Встроенное определение зависимостей
Fugly. Вы должны загромождать свои тесты большим количеством шаблонов AMD.
Загрузка фиктивных зависимостей с разных путей
Это включает использование отдельного файла config.js для определения путей для каждой из зависимостей, которые указывают на фиктивные, а не на исходные зависимости. Это также уродливо, требуя создания множества тестовых файлов и файлов конфигурации.
Подделка в узле
Это мое текущее решение, но оно все еще ужасное.
Вы создаете свою собственную
define
функцию, чтобы предоставить свои собственные макеты для модуля и помещать свои тесты в обратный вызов. Затем выeval
запускаете модуль для запуска тестов, например:Это мое предпочтительное решение. Это выглядит немного волшебно, но имеет несколько преимуществ.
eval
гнев и представить, как Крокфорд взрывается от ярости.Очевидно, у него все еще есть недостатки.
define
в каждом тесте, поскольку именно там ваши тесты и запускаются.Я работаю над тестовым средством запуска, чтобы дать более приятный синтаксис для такого рода вещей, но у меня до сих пор нет хорошего решения проблемы 1.
Вывод
Mocking deps в requirejs - отстой. Я нашел способ, которым это работает, но все еще не очень им доволен. Пожалуйста, дайте мне знать, если у вас есть идеи получше.
источник
Есть
config.map
вариант http://requirejs.org/docs/api.html#config-map .О том, как его использовать:
Настроить RequireJS явно;
В этом случае для нормального и тестового кода вы можете использовать
foo
модуль, который будет реальной ссылкой на модуль и, соответственно, заглушкой.источник
Вы можете использовать testr.js для имитации зависимостей. Вы можете настроить testr так, чтобы он загружал фиктивные зависимости вместо исходных. Вот пример использования:
Также проверьте это: http://cyberasylum.janithw.com/mocking-requirejs-dependencies-for-unit-testing/
источник
Этот ответ основан на ответе Андреаса Кёберле .
Мне было нелегко реализовать и понять его решение, поэтому я более подробно объясню, как оно работает, и некоторые подводные камни, которых следует избегать, надеясь, что это поможет будущим посетителям.
Итак, во-первых, настройка:
я использую Karma как средство запуска тестов и MochaJs как среду тестирования.
Использование чего-то вроде Squire у меня не сработало, по какой-то причине, когда я его использовал, тестовая среда выдавала ошибки:
RequireJs имеет возможность сопоставлять идентификаторы модулей с идентификаторами других модулей. Это также позволяет создать
require
функцию, которая использует конфигурацию, отличную от глобальнойrequire
.Эти функции имеют решающее значение для работы этого решения.
Вот моя версия имитационного кода, включая (много) комментариев (надеюсь, это понятно). Я обернул его внутри модуля, чтобы тесты могли легко потребовать его.
Самая большая ловушка , с которой я столкнулся, буквально стоила мне часов, - это создание конфигурации RequireJs. Я попытался (глубоко) скопировать его и переопределить только необходимые свойства (например, контекст или карту). Это не работает! Только скопируйте
baseUrl
, это отлично работает.использование
Чтобы использовать его, потребуйте его в своем тесте, создайте макеты, а затем передайте его
createMockRequire
. Например:А вот пример полного тестового файла :
источник
если вы хотите сделать несколько простых тестов js, которые изолируют один модуль, вы можете просто использовать этот фрагмент:
источник