Skip to content
This repository was archived by the owner on Dec 12, 2020. It is now read-only.

Commit f67e37a

Browse files
authored
finish mocking axios example (#361)
1 parent 7da59b8 commit f67e37a

File tree

12 files changed

+137
-64
lines changed

12 files changed

+137
-64
lines changed

.vscode/settings.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
{
22
"eslint.enable": false,
33
"editor.defaultFormatter": "esbenp.prettier-vscode",
4-
"editor.formatOnSave": true
4+
"editor.formatOnSave": true,
5+
"[json]": {
6+
"editor.defaultFormatter": "esbenp.prettier-vscode"
7+
},
8+
"json.format.enable": false
59
}

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -598,7 +598,7 @@ Spec | Description
598598
--- | ---
599599
[access-component](cypress/component/advanced/access-component) | Access the mounted component directly from test
600600
[i18n](cypress/component/advanced/i18n) | Testing component that uses [Vue I18n](https://kazupon.github.io/vue-i18n/) plugin
601-
[mocking-axios](cypress/component/advanced/mocking-axios) | Mocking 3rd party module imports, like `axios` for fetching data using a wrapper module
601+
[mocking-axios](cypress/component/advanced/mocking-axios) | Mocking 3rd party CommonJS modules like `axios`
602602
[mocking-components](cypress/component/advanced/mocking-components) | Mocking locally registered child components during tests
603603
[mocking-imports](cypress/component/advanced/mocking-imports) | Stub ES6 imports from the tests
604604
[render-functions](cypress/component/advanced/render-functions) | Mounting components with a [render function](https://www.tutorialandexample.com/vue-js-render-functions/)
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
/// <reference types="cypress" />
22
import { mount } from 'cypress-vue-unit-test'
3-
import AxiosGet from './AxiosGet.vue'
3+
import Users from './1-Users.vue'
4+
// we can load list of mock users straight from JSON file
5+
import mockUsers from './user.list.json'
46

57
// import everything from "axios" module
68
// so we can mock its methods from the test
7-
import * as Axios from 'axios'
9+
const Axios = require('axios')
810

911
describe('Mocking get import from Axios', () => {
10-
// https://github.com/bahmutov/cypress-vue-unit-test/issues/346
11-
it.skip('renders mocked data', () => {
12+
it('renders mocked data', () => {
1213
cy.stub(Axios, 'get')
1314
.resolves({
1415
data: [
@@ -20,12 +21,22 @@ describe('Mocking get import from Axios', () => {
2021
})
2122
.as('get')
2223

23-
console.log('Axios is', Axios)
24-
console.log('window.AxiosLib is', window.AxiosLib)
25-
console.log('window.AxiosLib === Axios?', window.AxiosLib === Axios)
26-
mount(AxiosGet)
24+
mount(Users)
2725
// mock response is used
2826
cy.get('li').should('have.length', 1)
2927
cy.get('@get').should('have.been.calledOnce')
3028
})
29+
30+
it('stubs with JSON loaded from fixture file', () => {
31+
cy.stub(Axios, 'get')
32+
.resolves({
33+
data: mockUsers,
34+
})
35+
.as('get')
36+
37+
mount(Users)
38+
// mock response is used
39+
cy.get('li').should('have.length', 2)
40+
cy.get('@get').should('have.been.calledOnce')
41+
})
3142
})

cypress/component/advanced/mocking-axios/AxiosGet.vue renamed to cypress/component/advanced/mocking-axios/1-Users.vue

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,6 @@
1212
<script>
1313
// import just the "get" from axios
1414
import {get} from 'axios';
15-
import * as Axios from 'axios';
16-
17-
window.AxiosLib = Axios
1815
1916
export default {
2017
data() {
@@ -25,10 +22,7 @@ export default {
2522
2623
// Fetches posts when the component is created.
2724
created() {
28-
console.log('get is', get)
29-
console.log('Axios is', Axios)
30-
31-
Axios.get('https://jsonplaceholder.cypress.io/users?_limit=3')
25+
get('https://jsonplaceholder.cypress.io/users?_limit=3')
3226
.then(response => {
3327
// JSON responses are automatically parsed.
3428
this.users = response.data
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/// <reference types="cypress" />
2+
import { mount } from 'cypress-vue-unit-test'
3+
import Users from './2-Users.vue'
4+
// we can load list of mock users straight from JSON file
5+
import mockUsers from './user.list.json'
6+
7+
// import everything from "axios" module
8+
// so we can mock its methods from the test
9+
const Axios = require('axios')
10+
11+
describe('Mocking get import from Axios', () => {
12+
it('renders mocked data', () => {
13+
cy.stub(Axios, 'get')
14+
.resolves({
15+
data: [
16+
{
17+
id: 101,
18+
name: 'Test User',
19+
},
20+
],
21+
})
22+
.as('get')
23+
24+
mount(Users)
25+
// mock response is used
26+
cy.get('li').should('have.length', 1)
27+
cy.get('@get').should('have.been.calledOnce')
28+
})
29+
30+
it('stubs with JSON loaded from fixture file', () => {
31+
cy.stub(Axios, 'get')
32+
.resolves({
33+
data: mockUsers,
34+
})
35+
.as('get')
36+
37+
mount(Users)
38+
// mock response is used
39+
cy.get('li').should('have.length', 2)
40+
cy.get('@get').should('have.been.calledOnce')
41+
})
42+
})

cypress/component/advanced/mocking-axios/AxiosGetRequire.vue renamed to cypress/component/advanced/mocking-axios/2-Users.vue

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<template>
22
<div>
3-
<h1>Axios Get</h1>
3+
<h1>Axios</h1>
44
<ul v-if="users && users.length">
55
<li v-for="user of users" v-bind:key="user.id">
66
<p><strong>{{user.id}}</strong> - {{user.name}}</p>
@@ -10,9 +10,8 @@
1010
</template>
1111

1212
<script>
13-
const Axios = require('axios')
14-
15-
window.AxiosLib = Axios
13+
// import the default axios
14+
import axios from 'axios';
1615
1716
export default {
1817
data() {
@@ -23,10 +22,7 @@ export default {
2322
2423
// Fetches posts when the component is created.
2524
created() {
26-
console.log('get is', get)
27-
console.log('Axios is', Axios)
28-
29-
Axios.get('https://jsonplaceholder.cypress.io/users?_limit=3')
25+
axios.get('https://jsonplaceholder.cypress.io/users?_limit=3')
3026
.then(response => {
3127
// JSON responses are automatically parsed.
3228
this.users = response.data

cypress/component/advanced/mocking-axios/mock-axios-wrapper-spec.js renamed to cypress/component/advanced/mocking-axios/3-Users.spec.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
/// <reference types="cypress" />
22
import { mount } from 'cypress-vue-unit-test'
3-
import Users from './Users.vue'
3+
import Users from './3-Users.vue'
4+
// test file can import the entire AxiosApi module
45
import * as AxiosApi from './AxiosApi'
56

67
describe('Mocking imports from Axios Wrapper', () => {
78
it('renders mocked data', () => {
8-
// stub export "get" that Users.vue imports and uses
9+
// stub export "get" that Users component imports and uses
910
cy.stub(AxiosApi, 'get')
1011
.resolves({
1112
data: [

cypress/component/advanced/mocking-axios/README.md

Lines changed: 52 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,71 @@
1-
# mocking axios
1+
# Mocking axios
22

3-
**Help wanted [#346](https://github.com/bahmutov/cypress-vue-unit-test/issues/346)**
3+
Axios is a 3rd party CommonJS module installed in `node_modules` and used from Vue components. To mock such module you have 3 choices, depending on how it is used.
44

5-
How can `import ... from '...'` be mocked from Vue and from JS spec files if the import is from `node_modules`? In plain JS files we use '@babel/plugin-transform-modules-commonjs' plugin so that all imports from file X are the same object and the individual properties can be stubbed using `cy.stub(X, 'import name')`. But the `vue-loader` used to transpile Vue files seems to not allow additional Babel plugins?
5+
## Named import
66

7-
See [mock-get-spec.js](mock-get-spec.js) and [AxiosGet.vue](AxiosGet.vue) for an open problem.
7+
If the component imports a single named property from a CommonJS module, the spec file can require the entire module and stub a property using [cy.stub](https://on.cypress.io/stub) command.
88

9-
## Workaround
9+
```js
10+
// component code
11+
import { get } from 'axios'
12+
get('...').then(...)
13+
14+
// spec file uses "require" to load the CommonJS module
15+
const Axios = require('axios')
16+
cy.stub(Axios, 'get').resolves({
17+
data: [
18+
{
19+
id: 101,
20+
name: 'Test User',
21+
},
22+
],
23+
})
24+
```
25+
26+
![Mocked get](./images/mock-get.png)
27+
28+
See [1-Users.vue](1-Users.vue) and [1-Users.spec.js](1-Users.spec.js) files.
29+
30+
## Method
31+
32+
If the component imports the entire CommonJS module, then calls its method, you still require the same module from the spec file.
33+
34+
```js
35+
// component code
36+
import axios from 'axios'
37+
axios.get('...').then(...)
38+
39+
// spec file uses "require" to load the CommonJS module
40+
const Axios = require('axios')
41+
cy.stub(Axios, 'get').resolves({
42+
data: [
43+
{
44+
id: 101,
45+
name: 'Test User',
46+
},
47+
],
48+
})
49+
```
50+
51+
See [1-Users.vue](1-Users.vue) and [1-Users.spec.js](1-Users.spec.js) files.
52+
53+
## Wrapped module
1054

11-
As a good workaround in this case, you can use an intermediate CommonJS wrapper module, like [AxiosApi.js](AxiosApi.js) that re-experts the CommonJS module; you can then mock those exports.
55+
Sometimes the component code uses an intermediate ES6 wrapper module, like [AxiosApi.js](AxiosApi.js) that re-experts the CommonJS module; you can then mock those exports.
1256

1357
```js
1458
// AxiosApi.js
1559
export * from 'axios'
1660
```
1761

18-
[Users.vue](Users.vue) shows the component that imports from `AxiosApi.js`
62+
[3-Users.vue](3-Users.vue) shows the component that imports from `AxiosApi.js`
1963

2064
```js
2165
import { get } from './AxiosApi'
2266
```
2367

24-
The test [mock-axios-wrapper-spec.js](mock-axios-wrapper-spec.js) mocks the "get" import.
68+
The test [3-Users.spec.js](3-Users.spec.js) mocks the "get" import.
2569

2670
```js
2771
import Users from './Users.vue'
400 KB
Loading

0 commit comments

Comments
 (0)