trojanowski / react-apollo-hooks

Use Apollo Client as React hooks
MIT License
2.41k stars 110 forks source link

Testing mutation component #124

Open mo-tottenham opened 5 years ago

mo-tottenham commented 5 years ago

I have a pie chart with a legend. When a legend label is clicked the corresponding pie slice gets a highlight color, and so does the legend label itself. This is the test for my Legend.tsx component.

I am getting the following error:

Missing field setActiveChart in {
      "activeChart": {
        "activeSegment": "Journal article",
        "type": "ResearchOutput"
      }
    }

Here is my test file:


import { ApolloClient } from 'apollo-client'
import { MockLink } from 'apollo-link-mock'
import React from 'react'
import { ApolloProvider } from 'react-apollo-hooks'
import { fireEvent, render } from 'react-testing-library'
import Legend from './'

const SET_ACTIVE_CHART = gql`
  mutation setActiveChart($activeSegment: String!, $type: String!) {
    setActiveChart(activeSegment: $activeSegment, type: $type) @client {
      activeSegment
    }
  }

const mocks = [
  {
    request: {
      query: SET_ACTIVE_CHART,
      variables: {
        activeSegment: 'Journal article',
        type: 'ResearchOutput',
      },
    },
    result: {
      data: {
        activeChart: {
          activeSegment: 'Journal article',
          type: 'ResearchOutput',
        },
      },
    },
  },
]
const data = [
  {
    name: 'Journal article',
    value: 75,
    colour: '#b2d5e0',
    percentage: 75,
  },
  {
    name: 'Books',
    value: 5,
    colour: '#99c7d5',
    percentage: 10,
  },
]
// afterEach(cleanup)

const createClient = clientmocks => {
  return new ApolloClient({
    cache: new InMemoryCache(),
    link: new MockLink(clientmocks),
  })
}

const waitForNextTick = () => new Promise(resolve => setTimeout(resolve))

describe('Legend: ResearchOutputByType', () => {
  const mockFunction = jest.fn()
  const client = createClient(mocks)
  const utils = render(
    <ApolloProvider client={client}>
      <Legend data={data} activeSegments={[]} setHoveredSegment={mockFunction} />
    </ApolloProvider>
  )
  test('Should render legend items', () => {
    expect(utils.container.textContent).toContain('Journal article')
  })
  test('Should update legend badge color on click', async () => {
    const el = utils.container.querySelector('#pie-legend-badge-0')
    const event = fireEvent.click(el)
    console.log('Badge click success:', event)
    await waitForNextTick()
    expect(true).toBe(false)
  })
})```
trojanowski commented 5 years ago

@mo-tottenham your result part of the mock seems incorrect. Please try to replace:

    result: {
      data: {
        activeChart: {

with

    result: {
      data: {
        setActiveChart: {
mo-tottenham commented 5 years ago

@trojanowski Ah ok I thought the result should match what the mutation returns which in my case was activeChart.

I've applied your suggested changes but then got an error about missing field __typename. So then I changed my mock mutation to this:

const SET_ACTIVE_CHART = gql`
  mutation setActiveChart($activeSegment: String!, $type: String!) {
    setActiveChart(activeSegment: $activeSegment, type: $type) @client {
      activeSegment
      type
    }
  }`

const mocks = [
  {
    request: {
      query: SET_ACTIVE_CHART,
      variables: {
        __typename: 'ActiveChart',
        activeSegment: 'Journal article',
        type: 'ResearchOutput',
      },
    },
    result: {
      data: {
        setActiveChart: {
          activeSegment: 'Journal article',
          type: 'ResearchOutput',
          __typename: 'ActiveChart',
        },
      },
    },
  },
]

Which gives me the following error:

No more mocked responses for the query: mutation setActiveChart($activeSegment: String!, $type: String!) {
      setActiveChart(activeSegment: $activeSegment, type: $type) @client {
        activeSegment
        __typename
      }
    }
    , variables: {"activeSegment":"Journal article","type":"ResearchOutput"}

Note: I also think the fact I am using the client directive as this mutation manages local state, could be an issue.

trojanowski commented 5 years ago

I also think the fact I am using the client directive as this mutation manages local state, could be an issue.

@mo-tottenham Yes, it could be the reason. Do you use Apollo Client 2.5? If so I think you should add your resolvers to the ApolloClient options.