javascript - 为浏览器编写 TSX 单元测试(JSX/React 的 TypeScript)

标签 javascript unit-testing reactjs typescript tsx

我一直在研究在 TypeScript 中开发基于 React 的组件的良好工作流程。

从 1.6 开始,TypeScript 通过 .tsx 扩展在 TypeScript 文件中原生支持 JSX,通过 tsd 我们可以获得 IDE (atom/WebStorm) 来支持类型检查.

但是,似乎没有一种简单的方法来测试用 tsx 编写的 React 组件。

您能分享一下您对此的见解吗?

我正在考虑(几乎不得不使用)Jest 而不是纯 Jasmine,因为 Jest 的运行时环境带有 DOM。然而,jest 似乎只能通过 babeles2015, react 预设与 ES2015 一起使用。 Jest 是否有现成的方式与 tsx 一起工作?

目前,我可以像这样测试用 ES2015 编写的 React 组件:

// SampleComponent.js

import React from 'react';

class SampleComponent extends React.Component {
  constructor(props) {
    super(props);
  }
  render() {
    return (<div className='container'>Hello World!</div>);
  }
}

module.exports = SampleComponent;

相应的测试可能如下所示:

// __tests__/SampleComponent-test.js

import React from 'react';
import ReactDOM from 'react-dom';
import TestUtils from 'react-addons-test-utils';

const SampleComponent = require('../SampleComponent');

describe('SampleComponent', ()=>{
  it("has some text", ()=>{

    const result = TestUtils.renderIntoDocument(
      <SampleComponent />
    );

    const sampleComponentNode = ReactDOM.findDOMNode(result);

    // expect statements

  });
});

这工作正常,但如果我们用 .tsx 替换 .js 扩展名,并将 scriptPreprocessor 更改为:

'use strict';

var ts = require('typescript');

module.exports = {
  process: function(src, path) {
    if (path.match(/\.(ts|tsx)$/) && !path.match(/\.d\.ts$/)) {
      return ts.transpile(src, {jsx: ts.JsxEmit.React, module: ts.ModuleKind.CommonJS});
    }
    return src;
  },
};

一切都乱套了,尤其是关于 TypeScript 处理模块加载的方式

最佳答案

经过探索,我找到了一个非常有效的暂定解决方案,尤其是当您的项目将 react 与其他框架集成时。

此解决方案确实需要精心设计的模块加载样板文件(我对仅前端项目感到恐惧)。我认为这种方法会持续到 ES6 模块加载成为标准。

暂定方案

测试运行器

业力

浏览器

phantomjs(因此它可以很容易地在 CI 服务器中使用)

引擎

Jasmine

转译器

tsc with --jsx react{"jsx": "react"} in tsconfig.json

使用库进行测试(例如 angular-mocks)

像这样将它们加载到 karma2.conf.js 中:

// list of files / patterns to load in the browser
    files: [
        // bind-polyfill helps phantomjs acquire the Function.prototype.bind function
        './node_modules/phantomjs-polyfill/bind-polyfill.js',
        "bower_components/jquery/dist/jquery.js",
        "bower_components/angular/angular.js",
        "bower_components/react/react-with-addons.js",
        "bower_components/react/react-dom.js",
        "bower_components/angular-mocks/angular-mocks.js",
        'src/**/*.js'
    ],

将所有 TS 文件编译成 ES5,不要export 符号

通过不从.ts.tsx 文件导出符号,编译后的js 文件可以简单地通过karma2 加载。 conf.js 如上所示。

为什么是 phantomjs?

它有一个 DOM,允许您渲染和操作 react 组件。 Facebook 自己的测试框架:Jest 提供相同的好处(与其他一些框架一样)。

缺点

由于 karma 使用浏览器并且文件以类似于传统网站的方式加载,因此可能很难加载不是用于后端的代码(即无法通过 Bower 获得)。例如,我没有使用 react TestUtils,而是被迫使用 jQuery + Phantom 提供的真实 DOM。

制作

正如 Louy 在评论中提到的,可以使用 webpack 或任何一种标准任务运行器

关于javascript - 为浏览器编写 TSX 单元测试(JSX/React 的 TypeScript),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34385772/

相关文章:

javascript - php 控制结构和 javascript 控制结构之间的区别

javascript - 如何在 Range 的末尾插入节点?

c# - .Net c# VisualStudio 2017执行测试,vstest.console.exe命令行说没有可用的测试

javascript - 代码返回 JSON 错误 Uncaught SyntaxError : Unexpected token :

javascript - 如何在另一个函数中使用一个 JavaScript 函数接收的 JSON 对象?

c# - NUnit、MSTest 和 xUnit 的选择性测试运行器

python测试结果报告

reactjs - dockerized React 应用程序中的 VSCode + Typescript

reactjs - Material-ui - Google 自动完成地址

javascript - 如何固定输入的位置,使其始终位于屏幕居中但其大小可以更改的元素下方?