#javascript #unit-testing #reactjs #jestjs
#javascript #модульное тестирование #reactjs #jestjs
Вопрос:
Я начал часто использовать Jest в новом проекте, и теперь я использую функциональность Jest для создания снимков.
В двух словах, что он делает, это отображает ваши компоненты в виде строки, сохраняет это на диске (в виде моментального снимка, который вы можете вернуть в свой репозиторий), и когда вы позже запустите свои тесты, он сравнит, что снимок не изменился.
Моя проблема связана с импортом изображений:
Обычный способ справиться с этим с помощью Jest — указать обработчик для их импорта, издеваться над ними и возвращать случайную строку. Таким образом, вашим тестам не нужно будет фактически загружать изображение, оно будет просто издеваться (в противном случае вы получите исключения, поскольку Node не знает, как обрабатывать import img from './image.png
, только Webpack делает это через загрузчик).
В конфигурации Jest вы бы сделали что-то вроде этого:
"jest": {
"moduleNameMapper": {
"^. \.(png|jpg|jpeg|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/app/__mocks__/fileMock.js",
"^. \.(css|less|scss)$": "identity-obj-proxy"
},
[...]
}
Как вы можете видеть, все изображения (png, jpeg и т.д.) «разрешаются» с помощью fileMock, который просто так:
module.exports = 'test-file-stub';
Моя проблема здесь в том, что издевательство заходит слишком далеко: оно всегда возвращает одну и ту же строку, что означает, что мои снимки для компонента, который отображает флаг, выглядят как:
exports[`components - Flag should match the snapshot 1`] = `
<img
alt="Flag"
className="image"
src="test-file-stub" />
`;
(входные данные были примерно такими <Flag country="fr" />
)
Я бы хотел, чтобы мой снимок отображался как таковой:
exports[`components - Flag should match the snapshot 1`] = `
<img
alt="Flag"
className="image"
src="/some/path/fr.png" />
`;
Я не верю, что я единственный, кто сталкивается с этой проблемой, но, с другой стороны, я нигде не смог найти какой-либо ресурс, решающий эту проблему.
Спасибо!
Ответ №1:
Вместо того, чтобы полагаться на moduleNameMapper
вы можете указать пользовательский transform
, в котором вы возвращаете путь к изображению вместо его источника. Рабочий пример можно найти в разделе Насмешливые CSS-модули, вставив его ниже, чтобы упростить задачу.
// fileTransformer.js
const path = require('path');
module.exports = {
process(src, filename, config, options) {
return 'module.exports = ' JSON.stringify(path.basename(filename)) ';';
},
};
и
// package.json (for custom transformers and CSS Modules)
{
"jest": {
"moduleNameMapper": {
"\.(css|less)$": "identity-obj-proxy"
},
"transform": {
"\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/fileTransformer.js"
}
}
}
Комментарии:
1. Ссылка недоступна. Теперь на facebook.github.io/jest/docs/en / …
2. Когда я использую мелкий рендеринг enzyme, я получаю src={ Object { «process»: [Функция], } }
3. я также получаю
src={ Object { "process": [Function], } }
с помощью storyshot4. Кому-нибудь повезло с этим и мелким рендерингом?
5. Есть ли способ получить полный путь к файлу вместо просто имени файла? Мой fileTransoformer просто возвращает «image.png» вместо «path / to / image.png».
Ответ №2:
Те, у кого возникли проблемы с предложением Valentin
и неглубоким рендерингом, могут попробовать включить эту строку в transform:
\.(js|jsx)$": "babel-jest"
чтобы это стало:
// package.json
{
"jest": {
"moduleNameMapper": {
"\.(css|less)$": "identity-obj-proxy"
},
"transform": {
"\.(js|jsx)$": "babel-jest",
"\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/fileTransformer.js"
}
}
}
Файл fileTransformer.js
остается тем же самым!
Примечание: Не смог прокомментировать его ответ, поскольку мне не хватает репутации 50 для комментариев; это мой первый ответ здесь!