【问题标题】:No query params when rendering routed component in unit test在单元测试中渲染路由组件时没有查询参数
【发布时间】:2021-02-17 08:35:32
【问题描述】:

我正在尝试测试我的 React 组件中的特定路由,该路由依赖于具有可见搜索参数的窗口。例如:

const MyComponent = () => {
    if (window.location.search) {
        return <h1 data-testid="query">Has search params</h1>
    }

    return <h1 data-testid="no-query">No search params</h1>
}

我对这种情况的测试是这样的:

it('should go down query route', () => {
    const initialState = configState(); // Set up Redux store

    const path = '/my-comp';
    const search = '?some=search';

    const history = createMemoryHistory({
        initialEntries: [{
           pathname: path, 
           search: search
        }]
    });
    history.push(redirectFrom);

    const mockStore = configureStore();
    
    const {queryByTestId} = render (
        <Provider store={mockStore(state)}>
           <Router history={history}>
              <MyComponent />
           </Router>
        </Provider>
    );
    
    expect(queryByTestId('query')).not.toBeNull();
    expect(queryByTestId('query').textContent).toBe('Has search params');

    expect(queryByTestId('no-query')).toBeNull();
});

我发现测试没有通过,所以我在组件的开头添加了一个console.log(window.location),以查看正在渲染组件的pathsearch 等,我发现所有缺少预期的属性:

{ 
    href: 'http://localhost/',
    origin: 'http://localhost',
    host: 'localhost',
    hostname: 'localhost',
    port: '',
    pathname: '/',
    search: '',
    hash: '' 
}

一些背景信息:

  • App 是用 Redux 构建的
  • 正如您所料,该组件在应用程序中呈现为&lt;Router&gt; 的一部分:
const App = () => {
    return (
        <Provider>
           <ConnectedRouter>
              <Route path="my-comp" component={MyComponent} />
              // More routes here
           </ConnectedRouter>
        </Provider>
    )
}

【问题讨论】:

  • 您是否尝试通过路由器获取它们,例如使用钩子,而不是直接从窗口对象?或者反过来在测试中的全局窗口对象上设置虚拟值?
  • @jonrsharpe 啊,我没有……我可能先看看虚拟窗口,然后再看看钩子——我想我昨天才看到它,所以值得研究一下。

标签: javascript html reactjs unit-testing testing


【解决方案1】:

感谢 @jonrsharpe 建议我查看路由器挂钩。

我最终使用了useLocation 钩子(我认为useParam 可以工作,但不幸的是这不会访问查询参数)。

这本质上是对我正在做的事情的直接交换。

之前

const MyComponent = () => {
    if (window.location.search) {
        return <h1 data-testid="query">Has search params</h1>
    }

之后

const MyComponent = () => {
    const location = useLocation();

    if (location.search) {
        return <h1 data-testid="query">Has search params</h1>
    }

执行此操作并保留 console.log 以显示正在呈现的组件完全显示了我在测试期间通过的模拟历史指定的内容:

const history = createMemoryHistory({
        initialEntries: [{
           pathname: path, 
           search: search
        }]
    });

【讨论】:

    猜你喜欢
    • 2018-10-11
    • 2022-01-23
    • 2021-07-11
    • 2021-09-07
    • 2021-12-23
    • 2020-08-15
    • 1970-01-01
    • 2021-01-18
    • 1970-01-01
    相关资源
    最近更新 更多