question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Allow ESM stubbing for functions in Vite

See original GitHub issue

What would you like?

Utilizing Vite + Vue and Cypress Component Test Runner, how would you stub a composable function since you can’t stub the default export?

I can’t find a decent example that doesn’t utilize Babel, and the only solution we have come up with is exporting an object with methods that can be stubbed, which, to be honest, would be a large refactor.

When stubbing the default export, as shown below, an error is thrown: ESModules cannot be stubbed. I know this is a valid error (here’s a great write-up for reference); however, we need the ability to stub the default exports of imported modules.

// Composable function
import { ref } from 'vue'

export default function useToggle (initialValue = false) {
  const enabled = ref(initialValue)

  return { 
    enabled
  }
}
// Component usage
import useToggle from '../composables/useToggle'
.... 
setup(props) {
  const { enabled } = useToggle(false)

  onMounted(() => console.log(enabled.value)
}
// test.spec.ts
import { ref } from 'vue'
import useToggle from '../composables/useToggle'

// This doesn't work, and we're not using Babel since switching to Vite
// Throws an error: `ESModules cannot be stubbed`
cy.stub(useToggle, 'default').returns(
  { 
    enabled: ref(true),
  }
)

Why is this needed?

It’s a standard in Vue 3 to move stateful logic into composable functions. Composables typically export a default function (not an object) and devs need the ability to stub the outputs of a composable.

There is currently a workaround; however, it would require refactoring large blocks of code within our (and most) application whereby the composable exports a utility function that is used to set the returned values. This workaround (shown below) is a bit cumbersome and requires a very explicit, non-standard way of writing composable functions.

Here is the same composable provided above, rewritten for the workaround (not ideal):

// Composable function
import { ref, Ref } from 'vue'

export const getToggleData = {
  enabled: (initialValue = false): Ref<boolean> => ref(initialValue)
}

export function useToggle(initialValue = false) {
  const enabled = getToggleData.enabled(initialValue)

  return {
    enabled,
  }
}
// Component usage
import useToggle from '../composables/useToggle'
.... 
setup(props) {
  const { enabled } = useToggle(false)

  onMounted(() => console.log(enabled))
}
// test.spec.ts
import { ref } from 'vue'
import { getToggleData } from '../composables/useToggle'

// This works, but isn't ideal due to the way the composable has to be written (not the norm)
cy.stub(getToggleData, 'enabled').returns(true)

Other

No response

Issue Analytics

  • State:open
  • Created a year ago
  • Comments:10 (5 by maintainers)

github_iconTop GitHub Comments

2reactions
iambumbleheadcommented, Sep 28, 2022

I’m interested in adding browser support to esmock. it would be awesome if someone would add a cypress test folder alongside esmock’s other test folders, and inside the test folder, add a passing test and a broken/failing test that uses esmock in the right place to try and browser-import a module with mock import tree.

1reaction
JessicaSachscommented, Jul 13, 2022

👋 You want @baus or @ZachJW34 for Next-y or roadmap planning things.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Features | Vite
Pre-bundle them to improve page loading speed and convert CommonJS / UMD modules to ESM. The pre-bundling step is performed with esbuild and...
Read more >
Configuring Vitest
To configure vitest itself, add test property in your Vite config. ... This might be helpful, if a dependency has the wrong ESM...
Read more >
How can I mock the imports of an ES6 module? - Stack Overflow
I'm using the following export setup with Mocha/Sinon and stubbing works fine without needing rewire, etc.: // MyModule.js let MyModule; export function ......
Read more >
Testing Vite with minimal config using Vitest - LogRocket Blog
Let's discuss how Vitest works, compare it with a popular test suite ... mock functions, spies, concurrent flags for parallel tests… the ...
Read more >
Embracing TypeScript and migrating to Vite and Vitest
vitest had great mocking support. To mock a global package you have to add at the top of the testing suite: import {...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found