使用链接测试子组件:在路由器上下文之外呈现的“<link />”无法导航。

时间:2017-02-03 17:25:36

标签: unit-testing react-router enzyme

我有一个按钮组件,可以创建react-router Link元素。它还允许传入onClick功能以获得其他功能(例如,发送Google Analytics事件)。

我已将此组件包含在父级中,如下所示:

export default class Page extends Component {
   const doSomething = () => {
    //do a thing to test here
   }

   return (
      <div>
         <Button
            onClickFn{() => doSomething()}
            linkToUrl='/other/page' //this creates a <Link> inside the button
          />
      </div>
   )
}

当我想测试正确触发doSomething时会出现问题。我使用了Enzyme mount来创建包含按钮的测试Page组件。当我模拟点击时,我收到以下错误

 '<Link>s rendered outside of a router context cannot navigate.'

因为按钮中的链接没有上下文。有没有办法嘲笑这个或防止错误显示?或者有更好的方法来测试此功能吗?

2 个答案:

答案 0 :(得分:3)

在测试中,您需要在<Router>内渲染组件。您可以查看tests for the <Link> component有关如何执行此操作的示例。

基本思想是创建一个内存历史记录实例,将其传递给<Router>,然后将<Link>内部的<Route>呈现给它。这听起来有点牵扯,但它相当简单。

import { createMemoryHistory } from 'history'

it('clicks', () => {
  const history = createMemoryHistory()
  const App = () => (
    <Router history={history}>
      <Route path='/' component={Page} />
    </Router>
  )
})

答案 1 :(得分:1)

在Paul的回答之上,这里有一个更详细的例子,用于测试onClick(或Button孩子的Link更准确)。该示例使用测试库mocha(BDD测试运行器),chai(BDD断言),酶(React测试实用程序)和sinon(测试双精度)。

import React from 'react';
import { Router, Route } from 'react-router';
import { createMemoryHistory } from 'history';

import MyCustomPage from '/.index';

describe('MyCustomPage', function(){
  it('stores data when clicking the link', function() {
    // Arrange
    const Page = () => (
      <MyCustomPage foo="foo" bar="bar" />
    );

    const container = enzyme.mount(
      <Router history={createMemoryHistory()}>
        <Route path="/" component={Page} />
      </Router>
    );

    // Act
    container.find('#my-link').simulate('click');

    // Assert
    expect(sessionStorage.setItem).to.have.been.calledWith('key', 'value');
  });
});