在过去的几个月里,我一直在React(通过react-apollo
)中使用ApolloJS,并且已经学会了与Apollo包装组件单元测试相关的一些技巧和挑战。
在测试直接用Apollo包装的组件时,我导出并测试组件,然后用graphql
返回的HoC进行包装。当测试具有Apollo包裹组件作为后代的组件时,我尽可能使用Enzyme的shallow
渲染来防止该后代的安装。如果需要通过mount
进行完整的DOM渲染,我使用来自Apollo测试工具的MockedProvider
,以便后代不会在尝试访问this.context
时抛出错误。
我没有找到解决方案,但是,对于以下情况:需要使用完整DOM渲染测试具有Apollo包装后代的组件,但我还需要进行涉及组件实例的断言(例如状态,实例方法)等)。为了避免后代出现问题,我必须将组件包装在模拟的提供程序中,但这意味着wrapper
上的任何断言都在MockedProvider
实例上运行,而不是我想要测试的组件。
一个例子:
import { mount } from 'enzyme'
import { MockedProvider } from 'react-apollo/lib/test-utils'
// This component has descendants that are wrapped in Apollo and
// thus need access to `this.context` provided by an Apollo provider
import Assignments from 'app/components/assignments
...
describe('<Assignments />', function() {
it('sets sorted assignments in initial state', function() {
const assignments = [...]
const wrapper = mount(
<MockedProvider>
<Assignments assignments={assignments} />
</MockedProvider>
)
// This will fail because the wrapper is of the MockedProvider
// instance, not the Assignments instance
expect(wrapper.state('assignments')).to.eql([...])
})
})
我试图通过Enzyme找到一种方法来访问一个孩子的组件实例,而不是根目录,根据我的判断,我不支持。我也一直试图在这些测试中找到需要MockedProvider
的替代品,但还没有找到任何东西。
有没有人为这种情况找到解决方法,或者我应该采用不同的方法来处理嵌套的Apollo包装组件?
答案 0 :(得分:4)
我找到了解决问题的方法。 Apollo包装的已安装组件的后代导致问题的原因是它们在尝试访问table_cube
时会抛出错误。 Apollo的this.context.client
创建了一个Apollo客户端(或者可选地使用你提供的客户端),并通过上下文将其提供给子女。
结果Enzyme的MockedProvider
方法允许您指定组件的context。我之前尝试过使用它,但没有意识到我还需要将它与childContextTypes结合起来,以便将该上下文传递给已安装组件的后代。使用这些酶选项可以避免使用mount
。
我将根据原始问题中提供的示例演示解决方案:
MockProvider
希望这有助于发现自己处于类似情况的人!