Skip to content
Snippets Groups Projects
Unverified Commit 740901c9 authored by Natalia Tepluhina's avatar Natalia Tepluhina Committed by GitLab
Browse files

Merge branch 'docs-document-vue-3-apollo-conflict' into 'master'

parents 8864d3de 6b5737fa
No related branches found
No related tags found
No related merge requests found
Loading
Loading
@@ -388,3 +388,8 @@ In [commit adding VueApollo v4 support](https://gitlab.com/gitlab-org/gitlab/-/c
 
- We might need to add additional imports to our facades (our code in GitLab uses `ApolloMutation` component)
- We need to update aliases not only for webpack but also for jest so our tests could also consume our facade
## Unit testing
For more information about implementing unit tests or fixing tests that fail while using Vue 3,
read the [Vue 3 testing guide](../testing_guide/testing_vue3.md).
Loading
Loading
@@ -6,6 +6,14 @@ info: Any user with at least the Maintainer role can merge updates to this conte
 
# Vue 3 Testing
 
## Running unit tests using Vue 3
To run unit tests using Vue 3, set the `VUE_VERSION` environment variable to `3` when executing jest.
```shell
VUE_VERSION=3 yarn jest #[file-path]
```
## Testing Caveats
 
### Ref management when mocking composables
Loading
Loading
@@ -116,3 +124,88 @@ describe('MyComponent', () => {
})
})
```
### Vue Apollo troubleshooting
You might encounter some unit test failures on components that execute Apollo mutations and
update the in-memory query cache, for example:
```shell
ApolloError: 'get' on proxy: property '[property]' is a read-only and non-configurable data property on the proxy target but the proxy did not return its actual value (expected '#<Object>' but got '#<Object>')
```
This error happens because Apollo tries to access or modify
a [Vue reactive object](https://vuejs.org/guide/essentials/reactivity-fundamentals.html) when we call the
`writeQuery` or `updateQuery` methods. As a general rule, never use a component's property in operations
that update Apollo's cache. If you must, use the `toRaw` utility to remove the Vue's reactivity proxy from
the target object.
The following example comes from a real-life scenario where this failure happened and provides two alternatives
to fix the test failure:
```html
<script>
import { toRaw } from 'vue';
export default {
props: {
namespace: {
type: String,
required: true,
},
agent: {
type: Object,
required: true,
},
},
methods: {
async execute() {
try {
await this.$apollo.mutate({
mutation: createClusterAgentMappingMutation,
update(store) {
store.updateQuery(
{
query: getAgentsWithAuthorizationStatusQuery,
variables: { namespace },
},
(sourceData) =>
produce(sourceData, (draftData) => {
const { mappedAgents, unmappedAgents } = draftData.namespace;
/*
* BAD: The error described in this section is caused by adding a Vue reactive
* object the nodes array. `this.agent` is a component property hence it is wrapped
* with a reactivity proxy.
*/
mappedAgents.nodes.push(this.agent);
unmappedAgents.nodes = removeFrom.nodes.filter((node) => node.id !== agent.id);
/*
* PREFERRED FIX: Use `toRaw` to remove the reactivity proxy.
*/
mappedAgents.nodes.push(toRaw(this.agent));
unmappedAgents.nodes = removeFrom.nodes.filter((node) => node.id !== agent.id);
/*
* ALTERNATIVE FIX: Only use data that already exists in the in-memory cache.
*/
const targetAgentIndex = removeFrom.nodes.findIndex((node) => node.id === agent.id);
mappedAgents.nodes.push(removeFrom.nodes[targetAgentIndex]);
unmappedAgents.nodes.splice(targetAgentIndex, 1);
}),
);
},
});
} catch (e) {
Sentry.captureException(e);
this.$emit('error', e);
}
},
},
};
</script>
```
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment