2

我正在使用酶、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 并且它没有被调用。

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

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

4

1 回答 1

4

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

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

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

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

示例反应组件:

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-02-03T01:17:21.567 回答