jest,enzyme - 测试返回jsx的方法

时间:2017-03-16 14:13:42

标签: javascript reactjs jestjs enzyme

我有以下组件:

import React, { Component } from 'react';
import {Link, IndexLink} from 'react-router';

class Navbar extends Component {

  renderLinks = (linksData) => {
    return linksData.map((linkData) => {
      if(linkData.to === '/') {
        return(
          <div className="navbar-link-container" key={linkData.to}>
            <IndexLink activeClassName="navbar-active-link" to={linkData.to}>
              <i className="navbar-icon material-icons">{linkData.icon}</i>
              <span className="navbar-link-text">{linkData.text}</span>
            </IndexLink>
          </div>
        )
      }
      else {
        return(
          <div className="navbar-link-container" key={linkData.to}>
            <Link activeClassName="navbar-active-link" to={linkData.to}>
              <i className="navbar-icon material-icons">{linkData.icon}</i>
              <span className="navbar-link-text">{linkData.text}</span>
            </Link>
          </div>
        )
      }
    })
  };

  render() {
    return (
      <div className={`navbar navbar-${this.props.linksData.length}`}>
        {this.renderLinks(this.props.linksData)}
      </div>
    )
  }
}

Navbar.propTypes = {
  linksData: React.PropTypes.array.isRequired,
};

export default Navbar;

现在我正在尝试编写一个单元测试来检查if条件(根据.to属性返回IndexLink或Link):

但是我似乎无法测试该函数的确切jsx返回,因为当我在console.log中获得一个返回时,我得到了这个:

  

{&#39; $$ typeof&#39;:Symbol(react.element),         输入:&#39; div&#39;,         key:&#39; /&#39;,         ref:null,         道具:          {className:&#39; navbar-link-container&#39;,            儿童:             {&#39; $$ typeof&#39;:符号(react.element),               类型:[对象],               key:null,               ref:null,               道具:[对象],               _owner:null,               _store:{}}},         _owner:null,         _store:{}}

这是我到目前为止所做的测试:

it('renderLinks should return a IndexLink', () => {
    const wrapper = shallow(<Navbar linksData={mockLinksData}/>);
    const renderLinksReturn = wrapper.instance().renderLinks(mockLinksData);
    let foundIndexLink = false;
    renderLinksReturn.map((linkHtml) => {
      console.log(linkHtml);
    });
    expect(foundIndexLink).toBe(true);
  })

现在我不知道要测试什么来查看函数是否正常运行。有没有办法安装&#39;像组件一样返回函数?或者是否有一个简单的方法来返回我可以检查的实际返回的html字符串?

4 个答案:

答案 0 :(得分:14)

面对类似的问题,我们将jsx组件作为prop传递给另一个组件。

你可以浅渲染返回的jsx ,因为它就像一个有效的React Function / Stateless Component。 例如:

const renderLinks = shallow(wrapper.instance().renderLinks(mockLinksData))

继续你常用的酶断言。

答案 1 :(得分:2)

我认为你不需要打电话

const renderLinksReturn = wrapper.instance().renderLinks(mockLinksData);

将在呈现Navbar时调用。

您的解决方案是正确的,但如果您想要一些其他可靠的方法来测试它。

由于此测试专门测试IndexLink并假设mockLinksData包含至=&#34; /&#34;

it('renderLinks should return a IndexLink when passed a link with to:\"/\"', () => {
    const wrapper = shallow(<Navbar linksData={mockLinksData}/>);

    // You can use both component name or component displayname
    // IndexLink or "IndexLink"
    expect(wrapper.find('IndexLink')).to.have.length(1);

    // In case you want to test whether indexLink has appropriate props or classes.
    const indexLink = wrapper.find(IndexLink).first();

   // Check whether indexLink has pass prop
   expect(indexLink.props().to).to.equal("/");

   // Check whether indexLink has correct classes set.
   expect(indexLink.hasClass('navbar-active-link')).to.equal(true);

  // Check whether indexLink displays the link test correctly
  expect(indexLink.find('navbar-link-text').text()).to.equal(mockLinksData.text);


 });

答案 2 :(得分:1)

原来,元素的类型存储在对象中。所以条件是:

props.children.type.displayName

我写的最终测试对于IndexLink来说是这样的:

it('renderLinks should return a IndexLink when passed a link with to:\"/\"', () => {
    const wrapper = shallow(<Navbar linksData={mockLinksData}/>);
    const renderLinksReturn = wrapper.instance().renderLinks(mockLinksData);
    let foundIndexLink = false;
    renderLinksReturn.map((linkHtml) => {
      {linkHtml.props.children.type.displayName === 'IndexLink' ? foundIndexLink = true : null};
    });
    expect(foundIndexLink).toBe(true);
  });

答案 3 :(得分:1)

要以@Nachiketha的答案为基础,当返回的内容是fragment时该语法将不起作用,可以通过将结果包装在div中来解决此问题,例如:

const renderLinks = shallow(<div>
    {wrapper.instance().renderLinks(mockLinksData)
    </div>
)}

this tread中的建议。

相关问题