首页 > 解决方案 > 使用酶时如何从路由器模拟位置

问题描述

我有以下代码...

 <BrowserRouter>
     <Switch>
         <Route path='/' exact component={Main} />
         <Route path='/transcript' component={Transcript} />
     </Switch>
</BrowserRouter>

// Inside Transcript...
constructor(props){
    super(props);
    let params = new URLSearchParams(location.search);
    if(!params.get("id")){
        throw new Error("Transcript must have id");
    }
    ...
}
// Test
describe("<Transcript />", ()=>{
    beforeAll(()=>{
        context.trans = shallow(<Transcript />)
    });
    it("Simple Test", ()=>{
        expect(context.trans.find("audio")).toBeDefined()
    })
});

当我尝试运行时,我收到一条错误消息,提示缺少参数。现在由于我没有使用浏览器,我不确定如何模拟这些信息。具体来说,我如何模拟 location.search 变量?

标签: reactjsjestjsenzyme

解决方案


一种选择是依赖注入:允许location(甚至可能search)作为道具传递给您的组件。你可以给 prop 一个window.location默认值,并在测试中传递一个特定的值。但是,您并没有测试默认值是否正确:)。

因此,如果您想测试您的函数是否正在从 window.location 检索一个值,那就有点棘手了。旧版本的 jsDOM(7 和更早版本)允许您在位置上定义属性,如下所示:

// somewhere in test setup
 Object.defineProperty(window.location, 'search', {
  writable: true,
  value: 'query=true'
});

但是现在 jsDOM 不允许你这样做(截至 jest 22+)。然而,还有一个替代方案。您可以使用testURLjest 配置属性为所有测试设置 url,但如果您的测试需要不同的配置,这将不起作用。但是如果你使用 pushState api,那么它可以用来设置 url:

window.history.pushState({}, 'Test Title', '/test.html?query=true')

如果其他事情关心历史 API,这可能会有一些警告,但可能适用于您的情况。

理想的方法是用来jsdom.reconfigure设置 url,但是 jest 使用的 jsdom 实例并不容易访问...

参考:


推荐阅读