Как добавить поддержку <canvas> в мои тесты в Jest?
В моем Jest unit test Я представляю компонент с ColorPicker. Компонент ColorPicker
создает объект canvas и 2d-контекст, но возвращает 'undefined'
, который выдает ошибку "Cannot set property 'fillStyle' of undefined"
if (typeof document == 'undefined') return null; // Dont Render On Server
var canvas = document.createElement('canvas');
canvas.width = canvas.height = size * 2;
var ctx = canvas.getContext('2d'); // returns 'undefined'
ctx.fillStyle = c1; // "Cannot set property 'fillStyle' of undefined"
У меня возникают проблемы, выясняя, почему я не могу получить 2d-контекст. Может быть, есть проблема с моей тестовой конфигурацией?
"jest": {
"scriptPreprocessor": "<rootDir>/node_modules/babel-jest",
"unmockedModulePathPatterns": [
"<rootDir>/node_modules/react",
"<rootDir>/node_modules/react-dom",
"<rootDir>/node_modules/react-addons-test-utils",
"<rootDir>/node_modules/react-tools"
],
"moduleFileExtensions": [
"jsx",
"js",
"json",
"es6"
],
"testFileExtensions": [
"jsx"
],
"collectCoverage": true
}
Ответы
Ответ 1
Это потому, что ваш тест не работает в реальном браузере. Jest использует jsdom
для насмешки над необходимыми частями DOM, чтобы иметь возможность запускать тесты в Node, таким образом избегая расчета стилей и рендеринга, что обычно делает браузер. Это круто, потому что это делает тесты быстрыми.
С другой стороны, если вам нужны браузерные API в ваших компонентах, это сложнее, чем в браузере. К счастью, в jsdom
есть поддержка canvas. Вы просто должны настроить это:
jsdom включает поддержку использования пакета canvas для расширения любых элементов <canvas>
с помощью API canvas. Чтобы это работало, вам нужно включить canvas в ваш проект как зависимость от jsdom. Если jsdom может найти пакет canvas, он будет его использовать, но если он не представлен, то элементы <canvas>
будут вести себя как <div>
s.
В качестве альтернативы вы можете заменить Jest каким-нибудь браузерным тестером, например, Karma. Шут в любом случае довольно глючит.
Ответ 2
Для тех, кто ищет примеры использования приложения create-реагировать
устанавливать
yarn add --dev jest-canvas-mock
Создайте новый ${rootDir}/src/setupTests.js
с
import 'jest-canvas-mock';
Ответ 3
У меня была такая же проблема. Я развертываю в gitlab ci для запуска своих тестов, а так как на холсте npm требуется установка Cairo, использование этого не было жизнеспособным вариантом.
Все, что я действительно хотел сделать, это издеваться над реализацией через Jest, чтобы он фактически не пытался создать реальный контекст. Вот как я это решил:
добавлено в package.json
"jest": {
"setupFiles": ["./tests/setup.js"],
}
тесты/setup.js
import sinon from 'sinon';
const createElement = global.document.createElement;
const FAKECanvasElement = {
getContext: jest.fn(() => {
return {
fillStyle: null,
fillRect: jest.fn(),
drawImage: jest.fn(),
getImageData: jest.fn(),
};
}),
};
/**
* Using Sinon to stub the createElement function call with the original method
* unless we match the 'canvas' argument. If that the case, return the Fake
* Canvas object.
*/
sinon.stub(global.document, 'createElement')
.callsFake(createElement)
.withArgs('canvas')
.returns(FAKECanvasElement);
Ответ 4
В моем случае использования я сделал простую палочку для обезьян, как это
beforeEach(() => {
const createElement = document.createElement.bind(document);
document.createElement = (tagName) => {
if (tagName === 'canvas') {
return {
getContext: () => ({}),
measureText: () => ({})
};
}
return createElement(tagName);
};
});
Не нужно устанавливать предварительно созданный холст или синус.
Ответ 5
npm install -D [email protected]
Это обеспечивает поддержку canvas для jest. Это даже работает, если кто-то получает ошибку из-за Lottie.js.
Ответ 6
Думаю, вам нужно jest-canvas-mock.
Установка
Это должно быть установлено только как зависимость развития (devDependencies), поскольку она предназначена только для тестирования.
npm я --save-dev jest-canvas-mock
Настройка
В вашем пакете. json под шутки создайте массив setupFiles и добавьте jest-canvas-mock в массив.
{
"jest": {
"setupFiles": ["jest-canvas-mock"]
}
}
Если у вас уже есть атрибут setupFiles, вы также можете добавить jest-canvas-mock в массив.
{
"jest": {
"setupFiles": ["./__setups__/other.js", "jest-canvas-mock"]
}
}
Ответ 7
Чтобы проверить вывод холста в jest, вам нужно сделать следующее:
Убедитесь, что вы используете хотя бы jsdom 13. Вы можете сделать это, включив пакет jsom для jest, для 14 это:
jest-environment-jsdom-fourteen
И настройка Jest для использования этого
jest --env=jest-environment-jsdom-fourteen
или в package.json
"jest": {
...
"testEnvironment": "jest-environment-jsdom-fourteen",
Включите пакет canvas
npm. (начиная с версии 2.x это включает в себя встроенную версию, поэтому предварительная сборка не рекомендуется).