如何用酶测试react-router链接?

时间:2017-08-06 03:00:51

标签: reactjs unit-testing testing react-router enzyme

我看到了很多类似的问题,但所有这些问题都显得过时或令人难以置信。

我有一个包含React Router Link组件的React组件,如下所示:

export default class Home extends Component {                                      
  render() {                                                                       
    return (                                                                       
      <div className="Home">  
        <Link to="/mission">Begin</Link>                                           
      </div>                                              
    );                                                                             
  }                                                                                
}

然后,我试图非常简单地测试Home组件包含Link组件,该组件具有to=/mission属性,使用Jest。因此,根据Testing React Router docs,我尝试了许多测试变体,但这段代码最简洁地展示了我想要实现的目标(示例使用jest-enzyme来简化):

it('includes link to Mission scene', () => {                                       
  const home = shallow(<MemoryRouter><Home /></MemoryRouter>);                                                              
  expect(home).toContainReact(<Link to="/mission">Begin</Link>)                    
});

显然,该代码有几个问题,其中最重要的是错误:

Warning: Failed context type: The context `router` is marked as required in `Link`, but its value is `undefined`.

但请注意关键位:我想渲染(如果可能)Home组件,以便单独测试该组件。同时,我试图将其包含在MemoryRouter或以某种方式获取上下文,以便我可以测试Link组件。

敏锐的潜在回答者会注意到这个问题实际上会阻止对该组件的所有隔离测试(而不仅仅是与React Router相关的测试),因为我无法对组件进行浅层渲染一点都不。

4 个答案:

答案 0 :(得分:3)

您可以使用Enzyme的find方法:

import { Link } from 'react-router';

it('includes link to Mission scene', () => {                                       
  const wrapper = shallow(<MemoryRouter><Home /></MemoryRouter>);
  expect(wrapper.find(Link).props().to).toBe('/mission');
 });

答案 1 :(得分:2)

这是来自官方文档的信息:

  

如果您尝试对其中一个呈现<Link>的组件进行单元测试   或者<Route>等等,你会得到一些关于上下文的错误和警告。   虽然您可能想要自己删除路由器上下文,但我们   建议您将单元测试包装在<StaticRouter>或a   <MemoryRouter>

link可能对您有用。

答案 2 :(得分:0)

您可以通过像其他常规html元素一样将组件名称作为字符串插入来进行查询

it('includes link to Mission scene', function() {
    const wrapper = shallow(<MemoryRouter><Home /></MemoryRouter>);
    expect(wrapper.find('Link').prop('to')).to.be.equal('/mission');
});

答案 3 :(得分:-2)

尝试<MemoryRouter><Route><Home /></Route></MemoryRouter>