Using with webpack
Jest pode ser usado em projetos que usam webpack para gerenciar assets, estilos e compilação. webpack de fato oferece alguns desafios únicos sobre outras ferramentas, pois integra-se diretamente com sua aplicação para permitir o gerenciamento de estilos, assets como imagens e fontes, juntamente com o ecossistema expansivo de ferramentas e linguagens para ser compiladas em JavaScript.
Um exemplo de webpack #
Vamos começar com um tipo comum de arquivo de configuração webpack e traduzi-lo para uma instalação de Jest.
// webpack.config.js module.exports = { module: { loaders: [ {exclude: ['node_modules'], loader: 'babel', test: /\.jsx?$/}, {loader: 'style-loader!css-loader', test: /\.css$/}, {loader: 'url-loader', test: /\.gif$/}, {loader: 'file-loader', test: /\.(ttf|eot|svg)$/}, ], }, resolve: { alias: { config$: './configs/app-config.js', react: './vendor/react-master', }, extensions: ['', 'js', 'jsx'], modules: [ 'node_modules', 'bower_components', 'shared', '/shared/vendor/modules', ], }, };
Se você tem arquivos de JavaScript que são transformados pelo Babel, você pode habilitar o suporte para Babel ao instalar o plugin babel-jest
. Transformações JavaScript sem Babel podem ser tratadas com a opção de configuração transform
do Jest.
Manipulação de assets estáticos #
Em seguida, vamos configurar o Jest para manipular elegantemente arquivos de assets, tais como folhas de estilo e imagens. Normalmente, esses arquivos não são particularmente úteis em testes, por isso podemos com segurança fazer a simulação (mock, em inglês) deles. No entanto, se você estiver usando CSS Modules é melhor simular (mock, em inglês) de um proxy para suas pesquisas className.
// package.json { "jest": { "moduleNameMapper": { "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/fileMock.js", "\\.(css|less)$": "<rootDir>/__mocks__/styleMock.js" } } }
E os próprios arquivos de simulação (mock, em inglês):
// __mocks__/styleMock.js module.exports = {};
// __mocks__/fileMock.js module.exports = 'test-file-stub';
Simulando CSS Modules #
Você pode usar um Proxy ES6 para simular (mock, em inglês) CSS Modules:
npm install --save-dev identity-obj-proxy
Em seguida, todas as suas pesquisas className no objeto de estilos serão retornadas como são (por exemplo, styles.foobar = = = 'foobar'
). Isto é muito útil para Teste de Snapshot em React.
// package.json (for CSS Modules) { "jest": { "moduleNameMapper": { "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/fileMock.js", "\\.(css|less)$": "identity-obj-proxy" } } }
Observe que o Proxy está habilitado no Node 6 por padrão. Se você ainda não está no Node 6, certifique-se de invocar Jest usando
node --harmony_proxies node_modules/.bin/jest
.
Se moduleNameMapper
não pode mais cumprir suas exigências, você pode usar a opção de configuração do Jest transform
para especificar como os assets são transformados. Por exemplo, um transformador que retorna o nome base de um arquivo (tal que require('logo.jpg');
retorna 'logo'
) pode ser escrito como:
// 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" } } }
Nós dissemos para Jest ignorar arquivos que correspondam a uma folha de estilo ou extensão de imagem, e em vez disso, exigem nossos arquivos de simulação (mock, em inglês). Você pode ajustar a expressão regular para coincidir com os tipos de arquivo que sua configuração do webpack lida.
Nota: se você estiver usando babel-jest com pre-processadores adicionais de código, você precisa definir explicitamente babel-jest como um transformador para o seu código JavaScript mapear arquivos . js
para o módulo de babel-jest.
"transform": { "^.+\\.js$": "babel-jest", "^.+\\.css$": "custom-transformer", ... }
Configurando Jest para encontrar nossos arquivos #
Agora que Jest sabe como processar nossos arquivos, precisamos informá-lo como encontrar eles. Para o modulesDirectories
e as opções de extensões
do webpack existem análogos diretos do Jest moduleDirectories
e opções moduleFileExtensions
.
// package.json { "jest": { "moduleFileExtensions": ["js", "jsx"], "moduleDirectories": ["node_modules", "bower_components", "shared"], "moduleNameMapper": { "\\.(css|less)$": "<rootDir>/__mocks__/styleMock.js", "\\.(gif|ttf|eot|svg)$": "<rootDir>/__mocks__/fileMock.js" } } }
Nota: <rootdir> é um símbolo especial que é substituído pelo Jest com a raiz do seu projeto. Na maioria das vezes, este será a pasta onde seu package.json está localizado a menos que você especificar uma opção personalizada
rootDir
na sua configuração.
Da mesma forma as funções de opção do webpack resolve.root
como configuração de variável env de NODE_PATH
, que pode ser definido, ou fazer uso da opção modulePaths
.
// package.json { "jest": { "modulePaths": [ "/shared/vendor/modules" ], "moduleFileExtensions": ["js", "jsx"], "moduleDirectories": ["node_modules", "bower_components", "shared"], "moduleNameMapper": { "\\.(css|less)$": "<rootDir>/__mocks__/styleMock.js", "\\.(gif|ttf|eot|svg)$": "<rootDir>/__mocks__/fileMock.js" } } }
E finalmente temos o alias
do webpack para lidar. Por isso nós podemos fazer uso da opção moduleNameMapper
novamente.
// package.json { "jest": { "modulePaths": [ "/shared/vendor/modules" ], "moduleFileExtensions": ["js", "jsx"], "moduleDirectories": ["node_modules", "bower_components", "shared"], "moduleNameMapper": { "^react(.*)$": "<rootDir>/vendor/react-master$1", "^config$": "<rootDir>/configs/app-config.js", "\\.(css|less)$": "<rootDir>/__mocks__/styleMock.js", "\\.(gif|ttf|eot|svg)$": "<rootDir>/__mocks__/fileMock.js" } } }
É isso! webpack é uma ferramenta complexa e flexível, então você pode ter que fazer alguns ajustes para atender às necessidades específicas do seu aplicativo. Felizmente, na maioria dos projetos, Jest deve ser flexível o suficiente para lidar com sua configuração do webpack.
Nota: Para configurações webpack mais complexas, você pode também querer investigar projetos tais como: babel-plugin-webpack-loaders.
Usando com webpack 2 #
webpack 2 oferece suporte nativo para módulos ES. No entanto, Jest é executado no Node e portanto requer que os módulos ES sejam transpilados para módulos CommonJS. Como tal, se você estiver usando webpack 2, você provavelmente vai querer configurar Babel para transpilar módulos ES para módulos CommonJS somente no ambiente de teste
.
// .babelrc { "presets": [ ["es2015", {"modules": false}] ], "env": { "test": { "plugins": ["transform-es2015-modules-commonjs"] } } }
Nota: Jest armazena em cache os arquivos para acelerar a execução do teste. Se você atualizou .babelrc e Jest ainda não está funcionando, tente executar Jest com
--no-cache
.
Se você usar importações dinâmicas (import('some-file.js').then(module => ...)
), você precisa ativar o plugin dynamic-import-node
.
// .babelrc { "presets": [ ["es2015", {"modules": false}] ], "plugins": ["syntax-dynamic-import"], "env": { "test": { "plugins": ["dynamic-import-node"] } } }