2017-09-13 16 views
1

私は過去数ヶ月間、ReactのApolloJSを使って作業していました(そして、ユニットテストに関連する多くのトリックと課題を学びました)ラップされたコンポーネント。ReactコンポーネントをマウントするユニットテストでApolloでラップされた子孫を処理する

Apolloで直接ラップされたコンポーネントをテストするとき、コンポーネントがエクスポートされ、HoCでラップされる前に、graphqlが返されます。子孫としてApolloでラップされたコンポーネントを持つコンポーネントをテストするとき、可能な限りEnzymeのshallowレンダリングを使用して、その子孫がマウントされないようにします。 mountで完全DOMレンダリングが必要な場合は、をApolloのテストユーティリティから使用して、子孫がthis.contextにアクセスしようとしてエラーをスローしないようにします。

しかし、Apolloでラップされた子孫を持つコンポーネントは、完全なDOMレンダリングを使用してテストする必要がありますが、コンポーネントインスタンスを含むアサーションも作成する必要があります(例:状態、インスタンスメソッドなど)。子孫との問題を避けるためには、虚偽のプロバイダでコンポーネントをラップする必要がありますが、のアサーションは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([...]) 
    }) 
}) 

私はむしろ私の知る限りサポートされていないルート、より子供のコンポーネントインスタンスにアクセスするための酵素を介した方法を見つけることを試みてきました。私はまた、これらのテストでMockedProviderが必要であるという選択肢を見つけることを試みてきましたが、まだ何も見つかりませんでした。

このような状況の回避策を見つけた人がいますか、または入れ子にされたApolloラップコンポーネントを処理する別のアプローチがありますか?

答えて

1

私は私の問題の解決策を見つけました。 Apolloでラップされたコンポーネントの子孫が問題を引き起こしたのは、this.context.clientにアクセスしようとするとエラーが発生するためです。 ApolloのMockedProviderは、Apolloクライアントを作成します(またはオプションで提供するものを使用します)。

酵素のmountメソッドでは、コンポーネントのcontextを指定できます。私は前にこれを試してみましたが、そのコンテキストがマウントされたコンポーネントの子孫に渡されるためには、それをchildContextTypesと組み合わせる必要があることを認識していませんでした。これらの酵素オプションを使用すると、MockProviderを使用する必要がなくなります。

import React from 'react' 
import { mount } from 'enzyme' 

// This is an Apollo client I configured in a separate module 
// with a mocked network interface. I won't go into details on 
// that here, but am happy to provide more details if someone asks 
import mockedClient from 'test/mocked_client' 

// 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(
     <Assignments assignments={assignments} />, 
     { 
     context: { client: mockedClient }, 
     childContextTypes: { 
      client: React.PropTypes.object.isRequired 
     } 
     } 
    ) 

    // This now passes! 
    expect(wrapper.state('assignments')).to.eql([...]) 
    }) 
}) 

うまくいけば、これは、似たような状況で自分自身を見つける人を支援します。

私は私の元の質問に提供された例は、オフに基づいて解決策を説明します!

関連する問題