如何使已声明的模块在 Enzyme 浅层渲染中可见?
How to make a declared module visible in Enzyme shallow render?
我一直在尝试找出当我在开玩笑的单元测试中使用酶浅渲染组件时如何找到我声明的模块。我有一个自定义声明的模块,如下所示:
// index.d.ts
declare module "_aphrodite" {
import {StyleDeclarationValue} from "aphrodite";
type CSSInputType = StyleDeclarationValue | false | null | void;
interface ICSSInputTypesArray extends Array<CSSInputTypes> {}
export type CSSInputTypes = CSSInputType | CSSInputType[] | ICSSInputTypesArray;
}
我的一个名为 closeButton 的组件使用了它:
// closeButton.tsx
import {CSSInputTypes} from "_aphrodite";
export interface ICloseButtonProps {
onClick: (event: React.MouseEvent<HTMLDivElement, MouseEvent>) => void;
cssStyles?: CSSInputTypes;
}
@injectable()
@observer
@autobind
export class CloseButton extends React.Component<ICloseButtonProps> {
// implementation
}
以及浅层渲染组件的简单单元测试:
// closeButton.test.tsx
import {shallow} from "enzyme";
import {CloseButton} from "../../common";
import * as React from "react";
describe("Common - Close Button", () => {
it("Shallow Render", () => {
const component = shallow(<CloseButton onClick={null}/>);
console.log(component);
});
});
当我运行测试时,出现以下错误:
这很奇怪,因为关闭按钮 class 不会抛出任何编译错误并且可以很好地映射模块。当我在本地 运行 我的项目时也是如此,它不会抛出任何关于无法找到 _aphrodite 模块的 运行 时间错误。看来这只是通过测试出现的。
现在我尝试更改 jest.config.json、tsconfig.json 和 webpack.config.js 设置中的各种设置,但没有成功。我希望比我更有经验的人知道需要做什么才能在 运行 在组件上进行浅渲染时找到我的 _aphrodite 模块。
以下是上述文件的设置:
// jest.config.json
{
"verbose": true,
"moduleFileExtensions": [
"ts",
"tsx",
"js"
],
"moduleDirectories": [
"node_modules",
"src"
],
"moduleNameMapper": {
"\.(jpg|jpeg|png|gif|svg)$": "<rootDir>/src/components/__tests__/_transformers/fileTransformer.js"
},
"transform": {
"\.(ts|tsx)$": "ts-jest"
},
"setupFiles": [
"<rootDir>/src/components/__tests__/setup.ts"
],
"testRegex": "(/__tests__/\.*|(\.|/)(test))\.tsx?$",
"testURL": "http://localhost/",
"collectCoverage": false,
"timers": "fake"
}
// tsconfig.json
{
"compileOnSave": true,
"compilerOptions": {
"rootDir": "./src",
"outDir": "./build/",
"sourceMap": true,
"noImplicitAny": true,
"module": "esnext",
"target": "es2018",
"jsx": "react",
"watch": false,
"removeComments": true,
"preserveConstEnums": true,
"inlineSourceMap": false,
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"lib": [
"dom",
"dom.iterable",
"es2018",
"esnext"
],
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"forceConsistentCasingInFileNames": true,
"moduleResolution": "node",
"isolatedModules": false
},
"include": [
"./src/**/*"
],
"exclude": [
"./node_modules"
]
}
// webpack.config.js
const HtmlWebpackPlugin = require("html-webpack-plugin");
const webpack = require('webpack');
const dotenv = require('dotenv');
const fs = require('fs'); // to check if the file exists
module.exports = () => {
return {
plugins: []
};
};
/**
* DevServer
*/
const devServer = {
inline: true,
host: "localhost",
port: 3000,
stats: "errors-only",
historyApiFallback: true,
watchOptions: {
poll: true
},
};
module.exports.getEnv = () => {
// Create the fallback path (the production .env)
const basePath = __dirname + '/.env';
// We're concatenating the environment name to our filename to specify the correct env file!
const envPath = basePath + ".local";
// Check if the file exists, otherwise fall back to the production .env
const finalPath = fs.existsSync(envPath) ? envPath : basePath;
// call dotenv and it will return an Object with a parsed key
const finalEnv = dotenv.config({path: finalPath}).parsed;
// reduce it to a nice object, the same as before
const envKeys = Object.keys(finalEnv).reduce((prev, next) => {
prev[`process.env.${next}`] = JSON.stringify(finalEnv[next]);
return prev;
}, {});
return new webpack.DefinePlugin(envKeys);
};
/**
* Plugins
*/
const plugins = [
new HtmlWebpackPlugin({
template: "./index.html"
}),
module.exports.getEnv()
];
module.exports = {
entry: "./src/index.tsx",
output: {
filename: "bundle.js",
path: __dirname + "/build",
publicPath: "/"
},
// Enable sourcemaps for debugging webpack's output.
devtool: "source-map",
resolve: {
// Add '.ts' and '.tsx' as resolvable extensions.
extensions: [".ts", ".tsx", ".js", ".json"]
},
module: {
rules: [
// All files with a '.ts' or '.tsx' extension will be handled by 'ts-loader'.
{test: /\.tsx?$/, loader: "ts-loader"},
// All output '.js' files will have any sourcemaps re-processed by 'source-map-loader'.
{enforce: "pre", test: /\.js$/, loader: "source-map-loader", exclude: [/node_modules/, /build/, /__test__/]},
{test:/\.css$/, use:['style-loader','css-loader'] },
{test:/\.(png|svg)$/, loader: "url-loader"},
{test:/\.mp3$/, loader: "url-loader" }
]
},
plugins: plugins,
devServer: devServer,
mode: "development",
performance: {
hints: false
}
};
这是我的项目结构:
如果需要更多信息,请随时询问。
原来我只需要将它添加到 jest.config.json
中的安装文件列表中
// jest.config.json
"setupFiles": [
"<rootDir>/src/components/__tests__/setup.ts",
"<rootDir>/src/aphrodite/index.ts"
],
我一直在尝试找出当我在开玩笑的单元测试中使用酶浅渲染组件时如何找到我声明的模块。我有一个自定义声明的模块,如下所示:
// index.d.ts
declare module "_aphrodite" {
import {StyleDeclarationValue} from "aphrodite";
type CSSInputType = StyleDeclarationValue | false | null | void;
interface ICSSInputTypesArray extends Array<CSSInputTypes> {}
export type CSSInputTypes = CSSInputType | CSSInputType[] | ICSSInputTypesArray;
}
我的一个名为 closeButton 的组件使用了它:
// closeButton.tsx
import {CSSInputTypes} from "_aphrodite";
export interface ICloseButtonProps {
onClick: (event: React.MouseEvent<HTMLDivElement, MouseEvent>) => void;
cssStyles?: CSSInputTypes;
}
@injectable()
@observer
@autobind
export class CloseButton extends React.Component<ICloseButtonProps> {
// implementation
}
以及浅层渲染组件的简单单元测试:
// closeButton.test.tsx
import {shallow} from "enzyme";
import {CloseButton} from "../../common";
import * as React from "react";
describe("Common - Close Button", () => {
it("Shallow Render", () => {
const component = shallow(<CloseButton onClick={null}/>);
console.log(component);
});
});
当我运行测试时,出现以下错误:
这很奇怪,因为关闭按钮 class 不会抛出任何编译错误并且可以很好地映射模块。当我在本地 运行 我的项目时也是如此,它不会抛出任何关于无法找到 _aphrodite 模块的 运行 时间错误。看来这只是通过测试出现的。
现在我尝试更改 jest.config.json、tsconfig.json 和 webpack.config.js 设置中的各种设置,但没有成功。我希望比我更有经验的人知道需要做什么才能在 运行 在组件上进行浅渲染时找到我的 _aphrodite 模块。
以下是上述文件的设置:
// jest.config.json
{
"verbose": true,
"moduleFileExtensions": [
"ts",
"tsx",
"js"
],
"moduleDirectories": [
"node_modules",
"src"
],
"moduleNameMapper": {
"\.(jpg|jpeg|png|gif|svg)$": "<rootDir>/src/components/__tests__/_transformers/fileTransformer.js"
},
"transform": {
"\.(ts|tsx)$": "ts-jest"
},
"setupFiles": [
"<rootDir>/src/components/__tests__/setup.ts"
],
"testRegex": "(/__tests__/\.*|(\.|/)(test))\.tsx?$",
"testURL": "http://localhost/",
"collectCoverage": false,
"timers": "fake"
}
// tsconfig.json
{
"compileOnSave": true,
"compilerOptions": {
"rootDir": "./src",
"outDir": "./build/",
"sourceMap": true,
"noImplicitAny": true,
"module": "esnext",
"target": "es2018",
"jsx": "react",
"watch": false,
"removeComments": true,
"preserveConstEnums": true,
"inlineSourceMap": false,
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"lib": [
"dom",
"dom.iterable",
"es2018",
"esnext"
],
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"forceConsistentCasingInFileNames": true,
"moduleResolution": "node",
"isolatedModules": false
},
"include": [
"./src/**/*"
],
"exclude": [
"./node_modules"
]
}
// webpack.config.js
const HtmlWebpackPlugin = require("html-webpack-plugin");
const webpack = require('webpack');
const dotenv = require('dotenv');
const fs = require('fs'); // to check if the file exists
module.exports = () => {
return {
plugins: []
};
};
/**
* DevServer
*/
const devServer = {
inline: true,
host: "localhost",
port: 3000,
stats: "errors-only",
historyApiFallback: true,
watchOptions: {
poll: true
},
};
module.exports.getEnv = () => {
// Create the fallback path (the production .env)
const basePath = __dirname + '/.env';
// We're concatenating the environment name to our filename to specify the correct env file!
const envPath = basePath + ".local";
// Check if the file exists, otherwise fall back to the production .env
const finalPath = fs.existsSync(envPath) ? envPath : basePath;
// call dotenv and it will return an Object with a parsed key
const finalEnv = dotenv.config({path: finalPath}).parsed;
// reduce it to a nice object, the same as before
const envKeys = Object.keys(finalEnv).reduce((prev, next) => {
prev[`process.env.${next}`] = JSON.stringify(finalEnv[next]);
return prev;
}, {});
return new webpack.DefinePlugin(envKeys);
};
/**
* Plugins
*/
const plugins = [
new HtmlWebpackPlugin({
template: "./index.html"
}),
module.exports.getEnv()
];
module.exports = {
entry: "./src/index.tsx",
output: {
filename: "bundle.js",
path: __dirname + "/build",
publicPath: "/"
},
// Enable sourcemaps for debugging webpack's output.
devtool: "source-map",
resolve: {
// Add '.ts' and '.tsx' as resolvable extensions.
extensions: [".ts", ".tsx", ".js", ".json"]
},
module: {
rules: [
// All files with a '.ts' or '.tsx' extension will be handled by 'ts-loader'.
{test: /\.tsx?$/, loader: "ts-loader"},
// All output '.js' files will have any sourcemaps re-processed by 'source-map-loader'.
{enforce: "pre", test: /\.js$/, loader: "source-map-loader", exclude: [/node_modules/, /build/, /__test__/]},
{test:/\.css$/, use:['style-loader','css-loader'] },
{test:/\.(png|svg)$/, loader: "url-loader"},
{test:/\.mp3$/, loader: "url-loader" }
]
},
plugins: plugins,
devServer: devServer,
mode: "development",
performance: {
hints: false
}
};
这是我的项目结构:
如果需要更多信息,请随时询问。
原来我只需要将它添加到 jest.config.json
中的安装文件列表中// jest.config.json
"setupFiles": [
"<rootDir>/src/components/__tests__/setup.ts",
"<rootDir>/src/aphrodite/index.ts"
],