# Test Renderer
如何引入
import TestRenderer from 'react-test-renderer'; // ES6
const TestRenderer = require('react-test-renderer'); // ES5 with npm
# 概览
这个 package 提供了一个 React 渲染器,用于将 React 组件渲染成纯 JavaScript 对象,无需依赖 DOM 或原生移动环境。
这个 package 提供的主要功能是在不依赖浏览器或 jsdom
的情况下,返回某个时间点由 React DOM 或者 React Native 平台渲染出的视图结构(类似与 DOM 树)快照。
示例:
import TestRenderer from 'react-test-renderer';
function Link(props) {
return <a href={props.page}>{props.children}</a>;
}
const testRenderer = TestRenderer.create(
<Link page="https://www.facebook.com/">Facebook</Link>
);
console.log(testRenderer.toJSON());
// { type: 'a',
// props: { href: 'https://www.facebook.com/' },
// children: [ 'Facebook' ] }
你可以使用 Jest 的快照测试功能来自动保存当前 JSON
树结构到一个文件中,并在测试中检查它是否被修改: 了解更多
。
你也可以通过遍历输出来查找特定节点,并对它们进行断言。
import TestRenderer from 'react-test-renderer';
function MyComponent() {
return (
<div>
<SubComponent foo="bar" />
<p className="my">Hello</p>
</div>
)
}
function SubComponent() {
return (
<p className="sub">Sub</p>
);
}
const testRenderer = TestRenderer.create(<MyComponent />);
const testInstance = testRenderer.root;
expect(testInstance.findByType(SubComponent).props.foo).toBe('bar');
expect(testInstance.findByProps({className: "sub"}).children).toEqual(['Sub']);
# TestRenderer
TestRenderer.create()
TestRenderer.act()
# TestRenderer instance
testRenderer.toJSON()
testRenderer.toTree()
testRenderer.update()
testRenderer.unmount()
testRenderer.getInstance()
testRenderer.root
# TestInstance
testInstance.find()
testInstance.findByType()
testInstance.findByProps()
testInstance.findAll()
testInstance.findAllByType()
testInstance.findAllByProps()
testInstance.instance
testInstance.type
testInstance.props
testInstance.parent
testInstance.children
# 参考
# TestRenderer.create()
TestRenderer.create(element, options);
通过传来的 React 元素创建一个 TestRenderer
实例。它并不使用真实的 DOM,但是它依然将组件树完整地渲染到内存,以便于你对它进行断言。此时将返回一个 TestRenderer 实例
。
# TestRenderer.act()
TestRenderer.act(callback);
与 react-dom/test-utils
中的 act()
相似,TestRender.act
为断言准备一个组件。可以使用 act()
来包装 TestRenderer.create
和 testRenderer.update
。
import {create, act} from 'react-test-renderer';
import App from './app.js'; // The component being tested
// 渲染组件
let root;
act(() => {
root = create(<App value={1}/>)
});
// 对根元素进行断言
expect(root.toJSON()).toMatchSnapshot();
// 更新 props
act(() => {
root.update(<App value={2}/>);
})
// 对根元素进行断言
expect(root.toJSON()).toMatchSnapshot();
# testRenderer.toJSON()
testRenderer.toJSON()
返回一个已渲染的的树对象。该树仅包含特定平台的节点,例如 或
和它们的 props,但并不包含任何用户编写的组件。这对于 快照测试
非常方便。
# testRenderer.toTree()
testRenderer.toTree()
返回一个已渲染的的树对象。它所表示的内容比 toJSON()
提供的内容要更加详细,并且包含用户编写的组件。除非你要在测试渲染器(test renderer)之上编写自己的断言库,否则你可能并不需要这个方法。
# testRenderer.update()
testRenderer.update(element)
使用新的根元素重新渲染内存中的树。它模拟根元素的一次 React 更新。如果新的元素和之前的元素有相同的 type 和 key,该树将会被更新;否则,它将重挂载一个新树。
# testRenderer.unmount()
testRenderer.unmount()
卸载内存中的树,会触发相应的生命周期事件。
# testRenderer.getInstance()
testRenderer.getInstance()
如果可用的话,返回与根元素相对应的实例。如果根元素是函数定义组件,该方法无效,因为函数定义组件没有实例。
# testRenderer.root
testRenderer.root
返回根元素“测试实例”对象,它对于断言树中的特定节点十分有用。你可以利用它来查找其他更深层的“测试实例”。
# testInstance.find()
testInstance.find(test)
找到一个 test(testInstance)
返回 true
的后代测试实例。如果不只有一个测试实例匹配,将会报错。
# testInstance.findByType()
testInstance.findByType(type)
找到匹配指定 type
的后代测试实例,如果不是只有一个测试实例匹配指定的 type
,将会报错。
# testInstance.findByProps()
testInstance.findByProps(props)
找到匹配指定 props
的后代测试实例,如果不是正好只有一个测试实例匹配指定的 props
,将会报错。
# testInstance.findAll()
testInstance.findAll(test)
找到所有 test(testInstance)
返回 true
的后代测试实例。
# testInstance.findAllByType()
testInstance.findAllByType(type)
找到所有匹配指定 type
的后代测试实例。
# testInstance.findAllByProps()
testInstance.findAllByProps(props)
找到所有匹配指定 props
的后代测试实例。
# testInstance.instance
testInstance.instance
该测试实例相对应的组件实例。它只能用于类定义组件,因为函数定义组件没有实例。它匹配给定的组件内部的 this
的值。
# testInstance.type
testInstance.type
该测试实例相对应的组件的类型。例如,一个 `` 组件有一个 Button
类型。
# testInstance.props
testInstance.props
该测试实例相对应的组件的 props。例如,一个 `` 组件的 props 为 {size: 'small'}
。
# testInstance.parent
testInstance.parent
该测试实例的父测试实例。
# testInstance.children
testInstance.children
该测试实例的子测试实例。
# 想法
你可以把 createNodeMock
函数作为选项(option)传递给 TestRenderer.create
,进行自定义 refs 模拟。createNodeMock
接受当前元素作为参数,并且返回一个模拟 ref 对象的。这十分有利于依赖 refs 组件的测试。
import TestRenderer from 'react-test-renderer';
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.input = null;
}
componentDidMount() {
this.input.focus();
}
render() {
return <input type="text" ref={el => this.input = el} />
}
}
let focused = false;
TestRenderer.create(
<MyComponent />,
{
createNodeMock: (element) => {
if (element.type === 'input') {
// 模拟 focus 函数
return {
focus: () => {
focused = true;
}
};
}
return null;
}
}
);
expect(focused).toBe(true);