【问题标题】:How to test child component method with Enzyme?如何用酶测试子组件方法?
【发布时间】:2017-07-03 20:50:04
【问题描述】:

我有一个这样的组件:

<Parent>
  <Child/>
</Parent>

&lt;Child/&gt; 组件有一个方法foo。我想测试foo 方法,但我不知道如何访问它。我试过了:

mount(<Parent><Child/></Parent>).props().children.foo

mount(<Parent><Child/></Parent>).children().foo

但他们都是undefined。我不能使用.instance(),因为它不是root。我无法挂载&lt;Child/&gt;,只是因为&lt;Parent&gt;context 上添加了一些东西(react-router 的context.router),并且在初始化&lt;Child/&gt; 时我需要它们。有什么想法吗?

【问题讨论】:

  • 这似乎仍然不可能或至少很复杂:github.com/airbnb/enzyme/issues/361
  • 在向上工作之前测试树中较低的反应组件。还要导出组件的解包版本以进行测试,以消除组件对反应路由器的依赖。
  • +1 关于编写反应规范最烦人的事情,我不明白你如何为反应编写规范框架并且没有一种简单的方法来访问子组件的实例。哑巴。

标签: javascript reactjs react-router enzyme


【解决方案1】:

这对我有用:

mount(<Parent><Child/></Parent>).find(Child).instance().foo

【讨论】:

  • 实例只能在root上调用。
  • 如何导入Child组件
【解决方案2】:

我会考虑只为你的父类编写测试,然后单独的测试文件只测试你的孩子。

一旦你安装了你的组件,使用:

const component = mount(<Child>); 

然后您可以使用以下方法访问它的方法:

component.instance().methodname

然后您可以使用 jest.fn() 覆盖它并进行适当的测试。

【讨论】:

  • 这在 React 16.x 中已经不可能了
【解决方案3】:

我更喜欢酶的浅安装而不是全安装。

结合 proxyquire 来解析子组件(你要测试的) 我愿意

wrapper.find('Child1').props().propName

然后测试一下。

或者我用浅的

mount wrapper.dive()

【讨论】:

    【解决方案4】:

    我认为您的问题与如何测试子组件完全不同。

    我的第一个问题是:为什么要检查子组件在父组件测试中是否有特定方法?

    恕我直言,您需要对此组件进行特定测试,然后在此测试中检查该方法是否存在。

    只是为了不离开没有答案,你试过.find(Child).instance().foo吗?

    【讨论】:

    • .instance() 只能在“root”上调用
    【解决方案5】:

    我在尝试在 MemoryRouter 的内部组件上模拟函数时遇到了类似的问题:

    cont wrapper = mount(<MemoryRouter><AvailabilityButtonWithRouter.WrappedComponent vetId={ vetId  } appointment={ availability } /></MemoryRouter>);     
    

    我最终能够像这样模拟函数:

    const mockFn = jest.fn();    
    wrapper.children(0).children(0).instance().reloadCurrentPage = mockFn;
    

    【讨论】:

    • 很好,它帮助我在 3 级嵌套 Item 子组件中找到了一个多次渲染的函数。不需要0 参数,如.children(0),而只需children()。当准备好找到它时,只需 .first().getElement() 和道具。我的例子:wrapper.find('Item').children().first().getElement()
    【解决方案6】:

    我能够获得如下子函数的句柄,我正在寻找第一个调用该函数的子函数 -

    const component = shallow(<Component />);
    component.find(Child).first().getNode().props.someChildFunction()
    

    【讨论】:

      【解决方案7】:

      我遇到了类似的问题,我通过日志记录了mount API。在我的用例中,我的子组件(CommonStoresReactions)用 mobx inject 包装。

      const jsx = (
          <Provider {...stores}>
            <CommonStoresReactions>
              <div />
            </CommonStoresReactions>
          </Provider>
      )
      const wrapper = mount(jsx)
      

      我想在CommonStoresReactions 中测试clearStores 方法。下面的 sn-p 对我有用。

      wrapper
            .find(CommonStoresReactions)
            .instance()
            .wrappedInstance.clearStores()
      

      【讨论】:

      • .instance() 只能在“root”上调用
      【解决方案8】:

      Enzyme 有一个名为 wrappingComponent(和 wrappingComponentProps)的 mount API 选项,可以将已安装的对象包装在另一个组件中以提供上下文等。

      https://github.com/airbnb/enzyme/blob/master/docs/api/mount.md#mountnode-options--reactwrapper

      【讨论】:

        【解决方案9】:

        我设法通过使用dive解决了这个问题

        wrapper.dive().props().propName
        

        【讨论】:

          【解决方案10】:

          含酶:

          mount(<Parent><Child/></Parent>).childAt(0).instance().foo
          

          有正当理由可以访问孩子并调用方法。如果父级是肤浅的并且子级具有一致的接口,您可以在不知道它是哪个子级的情况下调用方法,测试所有子级是否具有正确的接口、签名等。

          【讨论】:

            【解决方案11】:

            我发现最好的方法是使用浅包装器的dive 方法。这是文档:enzyme dive doc

            记住如果你的父组件使用像mount这样的完全渲染,那么react wrapper本身没有dive方法所以你必须使用浅渲染。

            这是一个例子:

            let instance, child, diveChild;
            describe('Test Parent child Child component', () => {
              beforeEach(() => {
                wrapper = shallow(<Parent {...props} />);
                child = wrapper.find('Child');
                diveChild = child.dive();
                console.log(diveChild.instance());
              });
            
              test('Child get mounted', () => {
                expect(child.exists()).toBeTruthy();
                expect(child.debug()).toMatchSnapshot();
              });
            });

            【讨论】:

              猜你喜欢
              • 2018-01-17
              • 2020-01-25
              • 1970-01-01
              • 2019-03-13
              • 1970-01-01
              • 1970-01-01
              • 2016-08-20
              • 1970-01-01
              • 2020-06-14
              相关资源
              最近更新 更多