this.props.location.query 最终在我的组件中未定义

this.props.location.query ends up being undefined in my component

这个问题在我的单元测试中偶尔会出现(开玩笑)。以下输出是 this.props.location 的样子:

this.props.location: Object {
  pathname: '/logs',
  search: '?hello=kitty',
  hash: '',
  state: null,
  action: 'POP',
  key: 'zn54se',
  query: undefined } <<< NOTE that i's undefined <<<<<

我不确定是什么原因造成的。以下是组件的设置方式:

// Logs.jsx:
...
renderToolbar() {
  var generateClassName = (destObj) =>
  {
    console.log("this.props.location:", this.props.location);
  }
  ...

  return <Button to="/logs" className={generateClassName({kind: 'all'})}>All</Button>;
}

render() {
  return <Grid toolbar={this.renderToolbar} />;
}

// Grid.jsx:
...
renderToolbar() {
  return this.props.toolbar ? this.props.toolbar() : '';
},

render() {
  return <div> { this.renderToolbar(); } </div>;
}

这是路线设置(在我的测试中):

describe('Logs', function() {
  var ts = (new Date()).valueOf();
  var node;
  beforeEach(function(){

    jest.setMock('myapp/lib/api/request', {});
    node = document.createElement('div');
    path = "/logs?hello=kitty";
    history = createHistory(path);
    routes = <Router history={history}><Route path="/logs" component={Logs} /></Router>;
  });

  it('should render one log entry', function() {
    LogStore.getLogs = jest.genMockFunction().mockReturnValue(
      [ {key: 0, kind: 'transfer', timestamp: ts, conn1name: 'Connector', conn2name: 'Connector2'} ]
    );

    var handler = ReactDOM.render(routes, node);

    expect(TestUtils.scryRenderedDOMComponentsWithClass(handler, 'log-entry').length).toBe(1);
  });
});

事实证明,jest 正在模拟 qs 模块,该模块是 react-router 的依赖项,用于生成查询对象。这就是它最终未定义的原因。

为了修复它,我在 package.json 中的 jest 设置中添加了 /qs

"jest": {
    "unmockedModulePathPatterns": [
        "/qs",
        ...
    ]
 }

在单元测试中为我解决了以下问题

<Router basename=""> <Switch> <Route history={history} path="/"> <MyApp/> </Route> </Switch> </Router>

其中历史定义如下

import createBrowserHistory from 'history/createBrowserHistory'; const history = createBrowserHistory({ basename: '/' });