次のコンポーネントがあります。
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戻りをテストするようには見えません。
{'$$ typeof':Symbol(react.element)、タイプ: 'div'、キー: '/'、参照:null、プロパティ:{className: 'navbar-link-container'、子:{'$$ typeof ':Symbol(react.element)、タイプ:[オブジェクト]、キー:null、参照: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);
})
現在、関数が正しく実行されているかどうかを確認するために何をテストするかわかりません。コンポーネントのように関数の戻りを「マウント」する方法はありますか?または、私がチェックできる実際のリターンのhtml文字列を返す簡単な方法はありますか?
電話する必要はないと思います
const renderLinksReturn = wrapper.instance().renderLinks(mockLinksData);
Navbar
がレンダリングされるときに呼び出されるため。
あなたの解決策は正しいですが、それをテストするためのいくつかの堅牢な代替方法が必要な場合に備えて。
このテストは特にIndexLink
をテストし、mockLinksData
にto = "/"が含まれていると想定しているため
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);
});
Jsxコンポーネントをプロップとして別のコンポーネントに渡す場合、同様の問題に直面しました。
これは、有効なReact Function/Stateless Componentのようなものであるため、返されたjsxを浅くレンダリングできます。例:
const renderLinks = shallow(wrapper.instance().renderLinks(mockLinksData))
通常の酵素のアサーションを続けます。
@Nachikethaの答えの上に構築するために、返されるものがfragment
の場合、その構文は機能しません。これは、結果をdiv
でラップすることで解決できます。
const renderLinks = shallow(<div>
{wrapper.instance().renderLinks(mockLinksData)
</div>
)}
this tread で提案されています。
要素のタイプがオブジェクトに格納されていることがわかります。したがって、条件は次のとおりです。
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);
});