Skip to main content
Version: Next

Usando com 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',
],
},
};

If you have JavaScript files that are transformed by Babel, you can enable support for Babel by installing the babel-jest plugin. Non-Babel JavaScript transformations can be handled with Jest's transform config option.

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:

yarn add --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.

If moduleNameMapper cannot fulfill your requirements, you can use Jest's transform config option to specify how assets are transformed. For example, a transformer that returns the basename of a file (such that require('logo.jpg'); returns 'logo') can be written as:

// 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"
}
}
}

Note: <rootDir> is a special token that gets replaced by Jest with the root of your project. Most of the time this will be the folder where your package.json is located unless you specify a custom rootDir option in your configuration.

Similarly, webpack's resolve.root option functions like setting the NODE_PATH env variable, which you can set, or make use of the modulePaths option.

// 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"
}
}
}

And finally, we have to handle the webpack alias. For that, we can make use of the moduleNameMapper option again.

// 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",
"^react(.*)$": "<rootDir>/vendor/react-master$1",
"^config$": "<rootDir>/configs/app-config.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. However, Jest runs in Node, and thus requires ES modules to be transpiled to CommonJS modules. As such, if you are using webpack 2, you most likely will want to configure Babel to transpile ES modules to CommonJS modules only in the test environment.

// .babelrc
{
"presets": [["env", {"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.

If you use dynamic imports (import('some-file.js').then(module => ...)), you need to enable the dynamic-import-node plugin.

// .babelrc
{
"presets": [["env", {"modules": false}]],
"plugins": ["syntax-dynamic-import"],
"env": {
"test": {
"plugins": ["dynamic-import-node"]
}
}
}

For an example of how to use Jest with Webpack with React, Redux, and Node, you can view one here.