【问题标题】:Testing React components with a .jsx extension使用 .jsx 扩展名测试 React 组件
【发布时间】:2016-11-03 03:01:10
【问题描述】:

我是 React 框架的新手,现在我正在探索在 React 中测试组件的方法。我在关注这个例子:https://www.codementor.io/reactjs/tutorial/test-reactjs-components-karma-webpack 使用 mocha 和 karma 为 React 设置单元测试框架。

我意识到我的所有组件都有 .jsx 扩展名,而不是 .js,因此我进行了更深入的研究。我知道需要先构建组件,然后才能导入/使用它们。

我尝试使用此示例:http://www.bebetterdeveloper.com/coding/getting-started-react-mocha.html。但这不包括业力。

如何使用 karma 来构建并导入 jsx 文件?

我正在使用 gulp 构建工件,我的 NodeJS 版本是 5.6

【问题讨论】:

  • 您想使用 Karma 有什么特别的原因吗?我可以发布一个答案,为您提供完整的测试设置,但我使用的是 Mocha 和 Chai,我不需要像 Karma 这样的测试运行器。
  • 好吧,没有使用 Karma 的具体原因。我正在关注教程,显然大多数示例都像业力或茉莉花一样。嗯是的。但是,接下来的问题是,难道不能使用 Karma、Mocha 和 gulp 吗?
  • 绝对有可能,只是我以前没有做过,所以我无法为您发布答案。但如果你同意放弃 Karma 或 Jasmine,我可以为你发布我的设置。
  • 我使用 karma 进行代码覆盖,但我猜你也可以通过 istanbul 做到这一点?如果您可以发布您的代码 sn-p,我绝对可以将其作为参考。最坏的情况,放弃因果报应,将摩卡与柴一起使用
  • 是的,我使用 Mocha、Chai、Istanbul 和 Enzyme 进行 React 测试设置。我可以在大约一个小时左右发布答案。

标签: javascript node.js reactjs


【解决方案1】:

这是一个使用 Mocha、Chai 和 jsdom 助手对 React 组件进行单元测试的简单示例,它用于代替 Karma 等测试运行器。

您将需要以下依赖项:

"dependencies": {
  "react": "^15.1.0",
  "react-dom": "^15.1.0"
},
"devDependencies": {
  "babel-preset-es2015": "^6.9.0",
  "babel-preset-react": "^6.11.1",
  "babel-register": "^6.9.0",
  "chai": "^3.5.0",
  "jsdom": "^9.3.0",
  "mocha": "^2.5.3"
}

拥有一个指向 mocha 的 npm 脚本也很有用 - npm run test 将执行您的测试:

"scripts": {
  "test": "./node_modules/.bin/mocha"
},

设置好依赖项后,您需要一个如下所示的目录结构:

.
├── /src
│   └── component-to-test.js
├── /test
│   ├── /unit
│   │   └── component-to-test.spec.js
│   ├── /util
│   │   └── jsdom.js
│   └── mocha.opts
├── .babelrc
└── package.json

我们将从您的 .babelrc 文件开始。您需要Babel 将您的 JSX 转换为 JavaScript。如果你想使用 ES6 语法(强烈推荐),Babel 也会提供帮助。我已经在 devDependencies 中包含了这两个预设。

.babelrc:

{
  "presets": ["es2015", "react"]
}

接下来,我们将看看 jsdom 助手。这是为了将 React 组件渲染到内存中的 DOM 中,这通常由 Karma 等测试运行程序处理。

jsdom.js:

(function () {
    'use strict';

    var jsdom = require('jsdom'),
        baseHTML,
        window;

    if (!global.window) {
        baseHTML = '<!DOCTYPE html><html><head lang="en"><meta charset="UTF-8"><title>Tests</title></head><body></body></html>';
        window = jsdom.jsdom(baseHTML).defaultView;

        global.window = window;
        global.document = window.document;
        global.navigator = window.navigator;
    }

}());

为了在我们的 mocha 测试中使用这个 jsdom 助手,我们需要设置一个 mocha.opts 文件来指定一些配置选项。我们将添加一个编译器,它会告诉 Babel 预处理测试,我们将 require jsdom 助手,以便 React 有一个 DOM 用于渲染组件。

mocha.opts:

--compilers js:babel-register
--recursive
--reporter spec
--ui bdd
--require ./test/util/jsdom.js

最后,我们可以开始测试 React 组件了。例如,这里有一个我们可以测试的简单组件。

test-component.js:

import React from 'react';

export default class TestComponent extends React.Component {
    render() {
        return (
            <div className="test-component">Here is a test component</div>
        );
    }
}

这里有一个测试套件,可以测试这个组件的标记。

test-component.spec.js:

import TestComponent from '../../src/test-component';
import {expect} from 'chai';

import React from 'react';
import ReactDOM from 'react-dom';
import ReactTestUtils from '../../node_modules/react/lib/ReactTestUtils';

describe('Test Component', () => {
    let renderedNode;

    function renderComponent() {
        const componentElement = React.createElement(TestComponent),
            renderedElement = ReactTestUtils.renderIntoDocument(componentElement);

        renderedNode = ReactDOM.findDOMNode(renderedElement);
    }

    beforeEach(() => {
        renderComponent();
    });

    it('should exist with the correct markup', () => {
        expect(renderedNode.tagName).to.equal('DIV');
        expect(renderedNode.className).to.equal('test-component');
        expect(renderedNode.textContent).to.equal('Here is a test component');
    });
});

此时,命令npm run test 应该会导致一次通过测试。

就是这样!如果您正在寻找更高级的测试技术,您可以完全避免对 jsdom 助手的需求,并为您的测试使用浅层渲染。如果您想采用这种方法,我强烈推荐Enzyme

如果您有任何问题,请告诉我!

【讨论】:

  • 这很棒。但是话又说回来,你所有的 react 组件文件的扩展名都是 .js 而不是 .jsx。这不会影响测试吗?
  • 不,您可以使用任一扩展名。唯一的区别是您在测试中的import 语句需要包含.jsx 文件扩展名。只有以.js 结尾的文件才允许省略扩展名。
  • 啊哈好吧。我会试试这个。这很棒。谢谢!
猜你喜欢
  • 2019-09-01
  • 2018-04-16
  • 2020-11-09
  • 2016-05-08
  • 1970-01-01
  • 1970-01-01
  • 2021-06-01
  • 1970-01-01
  • 2019-09-24
相关资源
最近更新 更多