Я реализую модульные тесты для моего приложения Apollo GraphQL с использованием библиотеки response-testing-library. Я использую MockedProvider для макетирования запросов и мутаций с сервера GraphQL. Я использую его, чтобы высмеивать запросы и мутации из кэша клиента Apollo. Но я не могу получить данные из фиктивных данных и кеша Apollo в одном компоненте. Вы когда-нибудь сталкивались с такой ситуацией? Пожалуйста, помогите мне!
- Когда я передаю mocks = {mocks} addTypename = {false} в MockedProvider, в UserList я получаю данные mockUserList из GET_USER_SEARCH_TEXT, но я получаю значение userSearchValue из undefined. Я получил ошибку и предупреждение:
TypeError: Cannot read property 'userSearchValue' of undefined
56 |
57 | const {
> 58 | data: { userSearchValue },
| ^
59 | } = useQuery(GET_USER_SEARCH_TEXT)
60 |
61 | const { loading, error, data, fetchMore, networkStatus } = useQuery(
at UserList (src/views/User/components/UserList/UserList.js:58:11)
at renderWithHooks (node_modules/react-dom/cjs/react-dom.development.js:14803:18)
at mountIndeterminateComponent (node_modules/react-dom/cjs/react-dom.development.js:17482:13)
at beginWork (node_modules/react-dom/cjs/react-dom.development.js:18596:16)
at HTMLUnknownElement.callCallback (node_modules/react-dom/cjs/react-dom.development.js:188:14)
at innerInvokeEventListeners (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:316:27)
at invokeEventListeners (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:267:3)
at HTMLUnknownElementImpl._dispatch (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:214:9)
at HTMLUnknownElementImpl.dispatchEvent (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:87:17)
at HTMLUnknownElement.dispatchEvent (node_modules/jsdom/lib/jsdom/living/generated/EventTarget.js:144:23)
at Object.invokeGuardedCallbackDev (node_modules/react-dom/cjs/react-dom.development.js:237:16)
at invokeGuardedCallback (node_modules/react-dom/cjs/react-dom.development.js:292:31)
at beginWork$1 (node_modules/react-dom/cjs/react-dom.development.js:23203:7)
at performUnitOfWork (node_modules/react-dom/cjs/react-dom.development.js:22157:12)
at workLoopSync (node_modules/react-dom/cjs/react-dom.development.js:22130:22)
at performSyncWorkOnRoot (node_modules/react-dom/cjs/react-dom.development.js:21756:9)
at scheduleUpdateOnFiber (node_modules/react-dom/cjs/react-dom.development.js:21188:7)
at updateContainer (node_modules/react-dom/cjs/react-dom.development.js:24373:3)
at node_modules/react-dom/cjs/react-dom.development.js:24758:7
at unbatchedUpdates (node_modules/react-dom/cjs/react-dom.development.js:21903:12)
at legacyRenderSubtreeIntoContainer (node_modules/react-dom/cjs/react-dom.development.js:24757:5)
at Object.render (node_modules/react-dom/cjs/react-dom.development.js:24840:10)
at node_modules/@testing-library/react/dist/pure.js:86:25
at batchedUpdates$1 (node_modules/react-dom/cjs/react-dom.development.js:21856:12)
at act (node_modules/react-dom/cjs/react-dom-test-utils.development.js:929:14)
at render (node_modules/@testing-library/react/dist/pure.js:82:26)
at _callee2$ (tests/views/User/components/UserList/UserList.test.js:98:19)
at tryCatch (node_modules/regenerator-runtime/runtime.js:45:40)
at Generator.invoke [as _invoke] (node_modules/regenerator-runtime/runtime.js:274:22)
at Generator.prototype.(anonymous function) [as next] (node_modules/regenerator-runtime/runtime.js:97:21)
at asyncGeneratorStep (node_modules/@babel/runtime/helpers/asyncToGenerator.js:3:24)
at _next (node_modules/@babel/runtime/helpers/asyncToGenerator.js:25:9)
at node_modules/@babel/runtime/helpers/asyncToGenerator.js:32:7
at Object.<anonymous> (node_modules/@babel/runtime/helpers/asyncToGenerator.js:21:12)
console.warn node_modules/ts-invariant/lib/invariant.js:33
Found @client directives in a query but no ApolloClient resolvers were specified. This means ApolloClient local resolver handling has been disabled, and @client directives will be passed through to your link chain.
- Когда я передаю cache = {cache} resolvers = {resolvers} mocks = {mocks} addTypename = {false} в MockedProvider, в UserList я получаю userSearchValue со значением, которое инициируется в кеше mockClient. Но я получил значение UserList неопределенного.
Компонент: UserList. js
import React from 'react'
import { useQuery } from '@apollo/react-hooks'
...
const FETCH_USER_LIST = gql`
query FetchUserList($query: UserListInput) {
userList(query: $query) {
items {
id
name
email
}
hasNext
}
}
`
const GET_USER_SEARCH_TEXT = gql`
query UserSearchValue {
userSearchValue @client
}
`
const UserList = props => {
const {
data: { userSearchValue },
} = useQuery(GET_USER_SEARCH_TEXT)
const { loading, error, data, fetchMore, networkStatus } = useQuery(
FETCH_USER_LIST,
{
variables: {
query: { searchText: '', limit: 30},
},
notifyOnNetworkStatusChange: true,
onError: err => {
alert(err)
},
}
)
console.log('data', data, 'userSearchValue', userSearchValue)
...
}
Тестовый файл: UserList.test. js
import React from 'react'
import { createMockClient } from 'mock-apollo-client'
import { InMemoryCache } from 'apollo-cache-inmemory'
import { act, cleanup, render } from '@testing-library/react'
import { UserList } from '@views/User/components'
import {
FETCH_USER_LIST,
GET_USER_SEARCH_TEXT,
GET_SELECTED_USER,
} from '@views/User/gql/query'
import { MockedProvider } from '@apollo/react-testing'
const mockUserList = [
{
id: '5e68995fb6d0bc05829b6e79',
name: '90412',
email: 'steve@example.com',
},
{
id: '5e68b5c3dd814dd832cda79d',
name: 'asdasdasd',
email: 'nvdai2355@gmail.com',
},
{
id: '5e68b792dd814d8efacda7ad',
name: 'nvdai235556',
email: 'nvdai235556@gmail.com',
},
]
const mocks = [
{
request: {
query: FETCH_USER_LIST,
variables: {
query: { searchText: '', limit: 30 },
},
fetchPolicy: 'no-cache',
notifyOnNetworkStatusChange: true,
},
result: {
data: {
userList: {
items: mockUserList,
hasNext: true,
},
},
},
},
]
const initialState = {
userSearchValue: '',
}
describe('UserList', () => {
const cache = new InMemoryCache()
cache.writeData({
data: { ...initialState, userSearchValue: 'search text' },
})
const mockClient = createMockClient({
cache,
resolvers: {},
})
afterEach(() => {
cleanup()
})
it('should match snapshot', () => {
const wrapper = render(
<MockedProvider
mocks={mocks}
addTypename={false}
cache={cache}
resolvers={resolvers}
>
<UserList />
</MockedProvider>
)
...
})
})
System:
OS: Window 10 1909 x64
Binaries:
Node: 10.18.1
Yarn: 1.21.1
npm: 6.13.4
Browsers:
Chrome: 80.0.3987.163
npmPackages:
"@apollo/react-hooks": "^3.1.4",
"@apollo/react-testing": "^3.1.4",
"@testing-library/cypress": "^6.0.0",
"@testing-library/jest-dom": "^5.3.0",
"@testing-library/react": "^10.0.2",
"apollo-client": "^2.6.8",
"apollo-cache-inmemory": "^1.6.5",
"apollo-link-context": "^1.0.19",
"apollo-link-schema": "^1.2.5",
"apollo-upload-client": "^12.1.0",
"graphql": "^14.6.0"