react单元测试

    科技2025-03-03  5

    react单元测试

    I know I said we weren’t going to cover Enzyme — but surprise! We are. While I understand the intention behind testing the user experience produced by code rather than the actual code implementation, the two are inextricably intertwined. Because of this, I find that Enzyme is not an alternative to React Testing Library, but rather an additional tool to use with it, and therefore is worth spending some time on.

    我知道我说过我们不打算介绍酶-但是令人惊讶! 我们是。 尽管我了解测试代码所产生的用户体验而不是实际代码实现背后的意图,但两者却密不可分。 因此,我发现Enzyme并不是React Testing Library的替代品,而是与其一起使用的附加工具,因此值得花一些时间。

    酶与React测试库 (Enzyme vs. React Testing Library)

    First off, how do the two libraries differ? We’ve already covered RTL (if you missed it, you can find it here), but as a quick recap, RTL is focused on testing the experience produced by the code. It tests the rendering of the code, as a user would.

    首先,两个库有何不同? 我们已经介绍过RTL(如果您错过了它,可以在这里找到它),但是快速回顾一下,RTL专注于测试代码产生的体验 。 它像用户一样测试代码的呈现。

    For instance, to submit a form, a user would look for a button with the text “Submit”, click on it, and then potentially see some kind of “success” message rendered to the DOM. Testing this using React Testing Library, you would find the button based on that “Submit” text, click on it, and then query for the text of that “success” message. Using Enzyme, however, you would test the functionality between the “click” and the “success” message.

    例如,要提交表单,用户将寻找带有文本“ Submit”的按钮,单击该按钮,然后潜在地看到呈现给DOM的某种“成功”消息。 使用React Testing Library对此进行测试,您将找到基于该“提交”文本的按钮,单击它,然后查询该“成功”消息的文本。 但是,使用酶可以测试“单击”和“成功”消息之间的功能 。

    Because of this foundational divergence, there is one particularly important contrast: Enzyme can directly test state and the manipulation of it, while React Testing Library cannot. This is the biggest reason that I choose to use Enzyme in conjunction with my other testing tools. There just are times when you need to directly test state, and directly test updating state. In doing so, I have caught bugs and inconsistencies that, while they did not affect the user’s experience, are not good code and could lead to negative UX affects down the line.

    由于这种基础上的差异,存在一个特别重要的对比:酶可以直接测试状态及其状态,而React Testing库则不能。 这是我选择与其他测试工具一起使用酶的最大原因。 有时候,您需要直接测试状态并直接测试更新状态。 这样做的时候,我发现了一些错误和不一致之处,尽管它们并没有影响用户的体验,但是它们并不是良好的代码,并且可能导致负面的UX影响。

    渲染组件 (Rendering a Component)

    Enzyme tests begin with actually rendering a React component, and for this, you have three choices: Shallow Rendering, Full DOM Rendering, and Static Rendering. We will cover the first two.

    酶测试从实际渲染React组件开始,为此,您有三个选择:“浅渲染”,“完整DOM渲染”和“静态渲染”。 我们将介绍前两个。

    浅层渲染 (Shallow Rendering)

    Shallow rendering is useful to constrain yourself to testing a component as a unit, and to ensure that your tests aren’t indirectly asserting on behavior of child components.

    浅呈现对于约束自己以一个单元测试组件,以及确保测试不会间接断言子组件的行为很有用。

    The above is from the Enzyme documentation. Shallow rendering is lighter weight than full DOM rendering. It should be used for tests that are limited in scope to the component being tested and do not need to test lifecycle methods. As a general rule, you can start with shallow rendering, and move to full DOM rendering when it does not meet your needs.

    以上是来自酶文档 。 浅渲染比完整DOM渲染轻。 它应用于范围仅限于被测组件且不需要测试生命周期方法的测试。 通常,您可以从浅层渲染开始,然后在不满足您的需求时转到完整DOM渲染。

    import { shallow } from 'enzyme';import MyComponent from './MyComponent';it('renders the component title', () => { const wrapper = shallow(<MyComponent />); expect(wrapper.find('.header')).to.have.lengthOf(1);});

    完整的DOM渲染 (Full DOM Rendering)

    Full DOM rendering is ideal for use cases where you have components that may interact with DOM APIs or need to test components that are wrapped in higher order components.

    对于具有可能与DOM API交互的组件或需要测试包装在高阶组件中的组件的用例,完全DOM呈现是理想的选择。

    Full DOM rendering is heavier weight, and should be used in place of shallow rendering when the component needs to access a resource outside of its own scope. It is more similar to testing in a full browser environment, as opposed to unit testing a singular component.

    完全DOM渲染的权重更大,当组件需要访问其自身范围之外的资源时,应使用纯DOM渲染代替浅渲染。 与单元测试单个组件相反,它更类似于在完整浏览器环境中进行测试。

    import { mount } from 'enzyme';import MyComponent from './MyComponent';it('calls componentDidMount', () => { const wrapper = mount( <MyComponent handleOnChange={handleOnChange} foo={bar} /> ); handleOnChange('baz'); wrapper.update(); expect(wrapper.props().foo).to.Equal('baz');});

    API参考 (API References)

    In the Enzyme documentation, you can find a full list of calls available to you with each type of rendering. These can be used to traverse the rendered component, assert something about the rendered component, or manipulate the rendered component.

    在“ 酶”文档中 ,您可以找到每种渲染类型可用的完整呼叫列表。 这些可用于遍历渲染的组件,声明有关渲染的组件的某些内容或操纵渲染的组件。

    遍历 (Traversal)

    Traversal allow you to find different elements within the component — elements which you can then manipulate or make an assertion on. These should look familiar to you at this point, from Jest and RTL:

    遍历允许您在组件中找到不同的元素,然后可以对其进行操作或声明。 现在,您应该从Jest和RTL中熟悉以下内容:

    contains(nodeOrNodes): Accepts a DOM node or nodes, and returns a boolean depending if the node/nodes are present in the rendered wrapper.

    contains(nodeOrNodes) :接受一个或多个DOM节点,并根据所呈现的包装器中是否存在一个或多个节点返回一个布尔值。

    children(selector): Optionally accepts a selector, and returns either all children of the current wrapper, or all children with the given selector of the current wrapper.

    children(selector) :可以选择接受一个选择器,并返回当前包装器的所有子代,或返回当前包装器具有给定选择器的所有子代。

    find(selector): Accepts a selector, and returns all nodes in the rendered wrapper that have the given selector.

    find(selector) :接受一个选择器,并返回呈现包装器中具有给定选择器的所有节点。

    findWhere(fn): Accepts a predicate function (a function that returns a boolean), and returns all nodes for which the predicate function is true.

    findWhere(fn) :接受谓词函数(一个返回布尔值的函数),并返回所有谓词函数为true节点。

    getElement(): Returns the wrapped element.

    getElement() :返回包装的元素。

    getElements(): Returns the wrapped elements.

    getElements() :返回包装的元素。

    parent(): Returns parent node of current wrapper.

    parent() :返回当前包装器的父节点。

    text(): Returns a string of rendered text in the wrapped component. Should be used sparingly, but can be used with calls like contain().

    text() :在包装好的组件中返回呈现的文本字符串。 应该谨慎使用,但可以与诸如contain()类的调用一起使用。

    操纵 (Manipulation)

    Manipulation calls are what I find to be the most beneficial reason to use Enzyme in addition to other tools. These allow you to change something about the implementation of the rendered component, such as state.

    我发现操纵调用是除了其他工具之外使用酶的最有益的原因。 这些允许您更改有关呈现组件实现的某些内容,例如state 。

    setContext(context): Accepts a context object, sets the context of the root component, and re-renders.

    setContext(context) :接受上下文对象,设置根组件的上下文,然后重新渲染。

    setProps(nextProps[, callback]): Accepts an object with new props and an optional callback function, sets the props of the root component and re-renders.

    setProps(nextProps[, callback]) :接受带有新道具和可选回调函数的对象,设置根组件的道具并重新渲染。

    setState(nextState[, callback]) / state(): Accepts an object with new state and an optional callback function, sets the state of the root component and re-renders. state() can be used to access the state object.

    setState(nextState[, callback]) / state() :接受具有新状态和可选回调函数的对象,设置根组件的状态并重新渲染。 state()可用于访问状态对象。

    simulate(event[, mock]): Similar to fireEvent() in RTL, accepts an event name as a string (ie, ‘click’) and an optional mock object, simulates the event on the root node of the wrapper.

    simulate(event[, mock]) :类似于RTL中的fireEvent() ,接受事件名称作为字符串(即,“单击”)和可选的模拟对象,在包装器的根节点上模拟事件。

    update(): Updates the Enzyme component tree to match the React component tree.

    update() :更新酶组分树以匹配React组分树。

    断言 (Assertions)

    Assertions should also look familiar at this point, and are the actual thing being tested about the element. After finding an element, you can something like, “it has text ‘Welcome to My App!’”.

    断言在这一点上也应该看起来很熟悉,并且是有关该元素的实际测试对象。 找到一个元素后,您可以像“它的文本为'Welcome to My App!'”。

    contains(nodeOrNodes): Accepts a node or nodes, returns a boolean based on whether the wrapper contains the given node/nodes.

    contains(nodeOrNodes) :接受一个或多个节点,根据包装器是否包含给定的一个或多个节点,返回一个布尔值。

    equals(node): Accepts a node, returns a boolean based on whether the wrapper is equal to the node passed in.

    equals(node) :接受一个节点,并根据包装器是否等于传入的节点返回一个布尔值。

    hasClass(className): Accepts a class name as a string, returns a boolean based on whether the wrapped node has the given class name.

    hasClass(className) :接受一个类名作为字符串,并根据包装的节点是否具有给定的类名返回一个布尔值。

    isEmpty(): Returns a boolean based on if the wrapper is empty.

    isEmpty() :根据包装是否为空,返回一个布尔值。

    some(selector): Accepts a selector, returns a boolean based on whether any nodes inside of the wrapper contain the given selector.

    some(selector) :接受一个选择器,根据包装器内部是否包含给定选择器的节点返回一个布尔值。

    还有一件事 (One More Thing)

    There is a lot of talk in the above about “the wrapped node” and “the wrapper”. To be clear, this can be any wrapped node that is returned from a call — not just the initial wrapper variable typically declared and assigned to the rendered component. This means that you can traverse the rendered component to find the node you wish to test, assign the found wrapper of the node/nodes to a new variable, and then use the above calls on this new wrapper:

    上面有很多关于“包装的节点”和“包装器”的讨论。 需要明确的是,这可以是从调用返回的任何包装节点,而不仅仅是通常声明并分配给呈现组件的初始wrapper变量。 这意味着您可以遍历渲染的组件以找到要测试的节点,将找到的一个或多个节点的包装器分配给新变量,然后在该新包装器上使用上述调用:

    import { mount } from 'enzyme';import MyComponent from './MyComponent';it('displays a header with text "Welcome!"', () => { const wrapper = mount(<MyComponent />); // Wraps the header node in a new wrapper on which to make calls const header = wrapper.find('.header'); expect(header).hasClass('header'); expect(header).to.equal('<div className="header">Welcome!</div>')});

    Now I can say, next we will be covering end to end testing with Cypress, after which we will circle back and walk through real-world implementation of testing in a real-world application.

    现在我可以说,接下来我们将介绍赛普拉斯的端到端测试,此后,我们将回顾并逐步介绍真实应用程序中的真实测试实现。

    资源资源 (Resources)

    Official Enzyme Documentation

    官方酶文件

    Running Tests with Create React App

    使用Create React App运行测试

    翻译自: https://medium.com/javascript-in-plain-english/testing-in-react-part-4-enzyme-9b030ad616ae

    react单元测试

    相关资源:四史答题软件安装包exe
    Processed: 0.014, SQL: 8