cypress-io / cypress-vue-unit-test

A little helper to unit test Vue components in the Cypress.io E2E test runner
295 stars 23 forks source link

Mocking import directly between Vue and node_modules #346

Closed bahmutov closed 4 years ago

bahmutov commented 4 years ago

How to mock axios import from a Vue component?

<script>
import * as Axios from 'axios';
...
// how to mock Axios.get?
Axios.get('https://jsonplaceholder.cypress.io/users?_limit=3')
  .then(response => {
}
</script>

We can try importing axios module and mocking a method

// spec.js
import * as Axios from 'axios'
cy.stub(Axios, 'get')
      .resolves({
        data: [
          {
            id: 101,
            name: 'Test User',
          },
        ],
      })
      .as('get')
    mount(AxiosGet)

The above fails, seems the imported modules are different objects. See PR #345 for code

Details

In other situations (and even in this library), I solve mocking ES6 imports by inserting a Babel plugin @babel/plugin-transform-modules-commonjs into the plugins list with these options

plugins: [
  // this plugin allows ES6 imports mocking
  [
    '@babel/plugin-transform-modules-commonjs',
    {
      loose: true,
    },
  ],
],

In "normal" JavaScript bundle this transform creates a shared object for every file

'./src/foo.js': { name: 'my name' },

and thus mocking the './src/foo.js'.name from the spec changes the value in every module that imports it too.

Seems in our situation the vue-loader and JavaScript combination do NOT share these objects. Maybe the @babel/plugin-transform-modules-commonjs is not applied to the JavaScript fragment after vue-loader loads it? Maybe the require cache is set up separately for the code from .vue files vs node_modules file, I don't know. External help would be welcome.

JessicaSachs commented 4 years ago

The js transforms defined in webpack are applied to the script portion.

bahmutov commented 4 years ago

:tada: This issue has been resolved in version 3.4.4 :tada:

The release is available on:

Your semantic-release bot :package::rocket: