javascript - 测试 React 组件 : How does it work?

标签 javascript reactjs jestjs

在 Jest 文档中,我找到了这个测试 React 组件的简单示例:

// Link.react.test.js
import React from 'react';
import Link from '../Link.react';
import renderer from 'react-test-renderer';

test('Link changes the class when hovered', () => {
  const component = renderer.create(
    <Link page="http://www.facebook.com">Facebook</Link>,
  );
  let tree = component.toJSON();
  expect(tree).toMatchSnapshot();

  // manually trigger the callback
  tree.props.onMouseEnter();
  // re-rendering
  tree = component.toJSON();
  expect(tree).toMatchSnapshot();

  // manually trigger the callback
  tree.props.onMouseLeave();
  // re-rendering
  tree = component.toJSON();
  expect(tree).toMatchSnapshot();
});

为什么我们必须导入 Reactreact-test-renderer,但不必导入其他测试特定的东西,比如 test , 期待?

谁能解释一下,这在幕后是如何工作的,以及在运行测试时实际发生了什么?

最佳答案

它找到二进制文件 jest 并用你的脚本执行它,这个二进制文件会先编译你的代码然后运行它,所以那些用于测试的模块将在编译时导入,当这些模块起作用时找到关键字。您将 Jest 安装到您的原始应用程序以测试组件。 React 模块或其他真正属于您的东西。

更新

通过追踪 Jest 的仓库 jest/packages/jest-runtime/src/script_transformer.js ,我们可以发现它利用了 Node.js 模块 VM运行脚本,它有一些方法,如 vm.createContext()vm.Script().runInContext(),所以这些内部模块应该导入到沙箱以编程方式。

示例来自 VM

const vm = require('vm');
const sandbox = { globalVar: 1 };            // <=> import expect, test 
vm.createContext(sandbox);
...
vm.runInContext('globalVar *= 2;', sandbox); // <=> Our test code.

所以像 expecttest 这样的模块可以像上面的 vm.createContext() 那样导入。

短时间内很难确切知道这是如何做到的,但我们仍然可以得到一些线索:

jest/packages/jest-runtime/src/cli/index.js

...
import Runtime from '../';  // --->  jest/packages/jest-runtime/src/index.js

export function run(...) {
   ...
   Runtime.createContext(
       ...
   ).then(
       const runtime = new Runtime(config, environment, hasteMap.resolver);
       runtime.requireModule(filePath);
       ...
   )
}

Runtime是定义在

中的关键类

jest/packages/jest-runtime/src/index.js

...

import Resolver from 'jest-resolve';

...

import ScriptTransformer from './script_transformer';

...

requireModule() {
    _execModule(...)
}

...

_execModule() {
    ...

    this._createRequireImplementation(

    ...

    this._createJestObjectFor(...)
}

这里有很多关键的工作,需要模块,检测环境配置,有 Resolver 来找到模块​​ id,检测什么样的模块,如果它被模拟,返回 jestObject,打包到我们的沙箱中进行测试。

这里是它的核心要做mock

关于javascript - 测试 React 组件 : How does it work?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49647469/

相关文章:

javascript - Legacy JavaScript 和 Javascript 之间最大的区别是什么?

javascript - 组合多个数组的相同索引的最佳方式

javascript - 在 React 中登录时加载主页

javascript - 删除输入之外的表单输入值

node.js - 单元测试 Nest JS Filter Catch 方法

reactjs - 在 componentDidMount 中获取数据后如何测试 React 组件?

javascript - React Router - 无法读取未定义的属性 'history'

javascript - 回调 spy 不会在流结束时被调用

reactjs - 使用样式化组件覆盖 react 组件样式

javascript - 不变失败 : You should not use <Switch> outside a <Router>