【问题标题】:How to sinon spy a React component constructor - unit testing?如何窥探 React 组件构造函数 - 单元测试?
【发布时间】:2016-11-29 01:22:09
【问题描述】:

我正在使用酶、sinon 并希望对我的反应组件进行单元测试。

import React from 'react';
import expect  from 'expect.js';
import { shallow } from 'enzyme';

import ExampleComponent from './../../../src/js/components/example-component';

describe('Test <ExampleComponent />', function() {

beforeEach(function() {
    this._sandbox = sinon.sandbox.create();
    this.constructorSpy = this._sandbox.spy(ExampleComponent.prototype, 'constructor');
});

afterEach(function() {
    this._sandbox.restore();
    this.constructorSpy = null;
});

it('Should set the state with the correct data [constructor]', function() {
    const wrapper = shallow(<ExampleComponent />);
    console.log(' - callCount: ', this.constructorSpy.callCount);
    expect(this.constructorSpy.calledOnce).to.be(true);

    expect(Immutable.is(wrapper.state('shownData'), Immutable.Map())).to.be(true);
});

我的组件构造函数中有一些逻辑,它根据我作为道具传入的内容来设置状态。但是,这个测试一直告诉我构造函数调用计数为 0,并且没有被调用。

监视组件构造函数的正确方法是什么?我做错了什么?

我正在使用沙盒,因为我想将其他功能添加到沙盒中以供将来监视。

【问题讨论】:

    标签: javascript unit-testing reactjs sinon expect.js


    【解决方案1】:

    当酶浅层渲染测试时,应自动调用构造函数(以及任何其他生命周期方法)。尝试在测试中覆盖它可能会非常复杂,并且对于您要检查的内容来说不是必需的。

    如果构造函数是根据 props 设置状态,为什么在测试中检查结果状态还不够? (请参阅下面我的示例中的“非常重要”断言)

    另一个选项:假设您正在设置状态中的项目,然后在组件渲染中使用 - 在这种情况下,您可以只检查渲染元素中的这些项目。

    最后,我还在构造函数中包含了一个函数调用,然后我在测试中监视它(使用 sinon)来断言它被调用,以防它有用。

    示例 React 组件:

    import React, { Component, PropTypes } from 'react'
    
    export default class Post extends Component {
      static propTypes = {
        markRead: PropTypes.func.isRequired,
        postName: PropTypes.string.isRequired
      }
    
      constructor (props) {
        super(props)
        const { markRead, postName } = props
    
        markRead()
        this.state = {
          postName: 'Very Important: ' + postName
        }
      }
    
      render () {
        const { postName } = this.state
    
        return (
          <div className='post-info'>
            This is my post: {postName}!
          </div>
        )
      }
    }
    

    示例酶测试,全部通过:

    import React from 'react'
    import assert from 'assert'
    import { shallow } from 'enzyme'
    import { spy } from 'sinon'
    
    import Post from 'client/apps/spaces/components/post'
    
    describe('<Post />', () => {
      const render = (props) => {
        const withDefaults = {
          markRead: () => {},
          postName: 'MyPostName',
          ...props
        }
        return shallow(<Post {...withDefaults} />)
      }
    
      it('renders and sets the post name', () => {
        const markReadSpy = spy()
        const props = {
          markRead: markReadSpy
        }
        const wrapper = render(props)
        const postInfo = wrapper.find('.post-info')
        const postText = postInfo.text()
    
        assert.equal(wrapper.state('postName'), 'Very Important: MyPostName')
        assert(markReadSpy.calledOnce)
        assert.equal(postInfo.length, 1)
        assert(postText.includes('MyPostName'))
      })
    })
    

    注意:另外,您在上面的示例中似乎没有导入 sinon。

    【讨论】:

      猜你喜欢
      • 2017-09-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-23
      • 2020-02-24
      • 1970-01-01
      相关资源
      最近更新 更多