开玩笑和酶的问题

时间:2019-09-13 16:35:42

标签: reactjs typescript jestjs enzyme

在Jest和Enzyme的单元测试中,我遇到了一些问题。 我正在使用带有Typescript和Emotion Framework的React。 我在Button Component上添加了一个简单的单元测试,只是为了查看测试是否有效。

// button.test.tsx
import React from 'react'
import { shallow } from 'enzyme'
import { Button } from '../button'

describe('First React component test with Enzyme', () => {
  it('renders without crashing', () => {
    shallow(<Button/>);
  })
})
// button.tsx
import React from 'react'
import { FunctionComponent, HTMLAttributes, ButtonHTMLAttributes } from 'react'
import { Icon } from '~/components'
import { styles } from './styles'

interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
  onClick?: () => any

  icon?: string
  color?: 'default' | 'accent' | 'accent-dark' | 'dark'
  size?: 'small' | 'medium' | 'big' | 'large'
  iconSize?: number
  withShadow?: boolean
}

export const Button: FunctionComponent<ButtonProps> = ({
  onClick,
  color = 'default',
  size = 'medium',
  icon,
  withShadow,
  children,
  ...props
}) => (
  <button
    css={[
      styles.base,
      styles.colors[color],
      styles.sizes[size],
      withShadow && styles.withShadow,
    ]}
    onClick={onClick}
    {...props}
  >
    {icon && (
      <span css={styles.icon[color === 'dark' ? 'dark' : 'default']}>
        <Icon icon={icon} size={color === 'dark' ? 16 : 12} />
      </span>
    )}
    {children}
  </button>
)

错误显示如下:

● Test suite failed to run

    ReferenceError: localStorage is not defined

      12 | 
      13 |   constructor() {
    > 14 |     this.token = localStorage.getItem('token') || null
         |                  ^
      15 | 
      16 |     if (this.token) {
      17 |       this.profile = this.decodeToken(this.token)

      at new UserStore (src/stores/user.ts:14:18)
      at Object.<anonymous> (src/stores/index.ts:4:26)
      at Object.<anonymous> (src/components/header/index.tsx:5:1)

我正在使用“ jsx”:“保留”作为构建的打字稿编译选项,并使用“ jsx”:“反应”用于开发笑话的打字稿编译选项。

// tsConfig.js
{
  "compilerOptions": {
    "target": "esnext",
    "module": "esnext",
    "lib": ["esnext", "dom"],
    "jsx": "preserve",
    "types": ["@emotion/core", "@types/node", "jest"],

    "moduleResolution": "node",
    "allowSyntheticDefaultImports": true,
    "esModuleInterop": true,
    "experimentalDecorators": true,

    "baseUrl": "./",
    "paths": {
      "~/*": ["src/*"]
    }
  },
  "presets": ["@babel/preset-env", "@babel/preset-react"],
  "include": ["src"]
}

这是开玩笑的配置:

// jestConfig.js

module.exports = {
  preset: 'ts-jest',
  testEnvironment: 'node',
  testMatch: ['**/src/**/*.test.ts?(x)', '**/?(*.)+(test).ts?(x)'],
  moduleNameMapper: {
    '\\.(jpg|jpeg|png|svg|ttf|woff|woff2)$':
      '<rootDir>/asset-transformer.js',
    '~(.*)$': '<rootDir>/src/$1'
  },
  globals: {
    'ts-jest': {
      tsConfig: {
        jsx: "react"
      }
    }
  },
  snapshotSerializers: [
      "enzyme-to-json/serializer"
    ],
    setupFiles: [
      "./test-shim.js",
      "./test-setup.js"
    ],
    moduleFileExtensions: [
      "ts",
      "tsx",
      "js",
      "jsx"
    ],
    transform: {
      "^.+\\.js(x)$": "babel-jest",
      "^.+\\.(ts|tsx)$": "./test-preprocessor.js"
    },
    testMatch: [
      "**/*.test.(ts|tsx|js|jsx)"
    ]
}
// .babel.rc
{
  "plugins": [
    [
      "transform-inline-environment-variables"
    ],
    [
      "babel-plugin-jsx-pragmatic",
      {
        "export": "jsx",
        "module": "@emotion/core",
        "import": "___EmotionJSX"
      }
    ],
    [
      "@babel/plugin-transform-react-jsx",
      {
        "pragma": "___EmotionJSX",
        "pragmaFrag": "React.Fragment"
      }
    ],
    [
      "emotion",
      {
        "sourceMap": true,
        "autoLabel": false,
        "cssPropOptimization": true
      }
    ],
    [
      "@babel/plugin-syntax-dynamic-import"
    ]
  ],
  "presets": [
    [
      "@babel/preset-env",
      {
        "modules": false,
        "targets": {
          "node": "current"
        }
      }
    ],
    "@babel/preset-typescript"
  ],
}

1 个答案:

答案 0 :(得分:0)

解决此问题有几种方法,但其目的是利用嘲弄/间谍。

1)监视localStorage的原型。 github上有一个与此问题有关的讨论。

jest.spyOn(window.localStorage.__proto__, 'setItem');

2)模拟localStorage本身的方法。它们在Stackoverflow上的其他post中得到了充分的介绍。