GithubHelp home page GithubHelp logo

Mock dependency about esmock HOT 8 CLOSED

yumauri avatar yumauri commented on June 11, 2024
Mock dependency

from esmock.

Comments (8)

iambumblehead avatar iambumblehead commented on June 11, 2024

I'm not too familiar with this scenario. esmock essentially looks up module paths using logic per import.meta.resolve https://nodejs.org/api/esm.html#importmetaresolvespecifier-parent and applies the specified mock to the definition loaded at the path.

@yumauri in your opinion, how should esmock support the situation you describe?

from esmock.

iambumblehead avatar iambumblehead commented on June 11, 2024

@yumauri what do you think of something like this?

import test from 'node:test'
import assert from 'node:assert/strict'
import esmock from 'esmock'
import depvsn1 from '../path/to/dep-vsn1.0.0.js'
import depvsn2 from '../path/to/dep-vsn2.0.0.js'

test('my-script with dep version 1', async () => {
  const scriptUsingDepVsn1 = await esmock('../my-script.js', {}, {
    dep: depvsn1
  })

  assert.ok(scriptUsingDepVsn1.usingDependencySucceeds())
})

test('my-script with dep version 2', async () => {
  const scriptUsingDepVsn2 = await esmock('../my-script.js', {}, {
    dep: depvsn2
  })

  assert.ok(scriptUsingDepVsn2.usingDependencySucceeds())  
})

from esmock.

iambumblehead avatar iambumblehead commented on June 11, 2024

There may well be a simpler way to do this I'm unaware of. I'm just not familiar with this situation where a file uses different version of the same dependency

from esmock.

iambumblehead avatar iambumblehead commented on June 11, 2024

@yumauri another idea if it is reasonable to do so, the add-on package being testing could use separated test-suites for each version of the dependency that is used. esmock, for example, uses different test runner and typescript loader combinations and uses separated test suites for those https://github.com/iambumblehead/esmock/tree/master/tests

from esmock.

yumauri avatar yumauri commented on June 11, 2024

Thing is I want to run same tests. For now I have 34 test suites with 171 tests in total. I would not like to double them all, this sounds like nightmare.

Unfortunately, I'm not familiar with module resolution in Node, and how rewiremock doing it... So I'm not sure about how API should look like. Maybe some way to globally intercept into module resolution process. This is how it looks like with rewirework, at least.

// esmock.mjs
import esmock from 'esmock'
import library_v1 from 'library_v1'
import library_v2 from 'library_v2'

const useVersion = process.env.USE_LIBRARY_VERSION || 'v1'
const library = useVersion === 'v1' ? library_v1 : library_v2

export default esmock.resolve('library').with(library)

and then use this file as loader

NODE_OPTIONS=--loader=./esmock.mjs ...

Other possible solution for my task — is to actually reinstall library to other version each time before running tests. And do not mock it at all. This sounds not too appealing as well, but I'm thinking about it too.

from esmock.

yumauri avatar yumauri commented on June 11, 2024

I'm just not familiar with this situation where a file uses different version of the same dependency

This is called back compatibility :) I want to be sure, that my library works as intended with different versions of 3rd party library. At least with two latest major versions.

from esmock.

iambumblehead avatar iambumblehead commented on June 11, 2024

@yumauri thank you that is an interesting and clear example given there. esmock does not support that sort of scenario now but your example shows how it could be useful.

Possibly quibble is a better mocking package for your use-case https://github.com/testdouble/quibble

Currently, one would need to need to generate a new import tree for each test to include the dependency version needed by the test.

import test from 'node:test'
import assert from 'node:assert/strict'
import esmock from 'esmock'
import libraryV1 from '../path/to/library-vsn1.0.0.js'
import libraryV2 from '../path/to/library-vsn2.0.0.js'

const myScriptWithLibVersion = async () => esmock('../my-script.js', {}, {
  dep: process.env.USE_LIBRARY_VERSION === 'v1'
    ? libraryV1
    : libraryV2
})

test('my-script behaviour A', async () => {
  const myScript = await myScriptWithLibVersion()

  assert.ok(myScript.behaviourASucceeds())
})

test('my-script behaviour B', async () => {
  const myScript = await myScriptWithLibVersion()

  assert.ok(myScript.behaviourBSucceeds())
})

if statefulness of the dependency does not present a problem, the same import tree could be returned to all callers eg something like this

import test from 'node:test'
import assert from 'node:assert/strict'
import esmock from 'esmock'
import libraryV1 from '../path/to/library-vsn1.0.0.js'
import libraryV2 from '../path/to/library-vsn2.0.0.js'

const myScriptWithLibVersion = async () => esmock('../my-script.js', {}, {
  dep: process.env.USE_LIBRARY_VERSION === 'v1'
    ? libraryV1
    : libraryV2
})

const myScriptWithLibVersionCached = (c => async () =>
  c || (c = myScriptWithLibVersion()))()

test('my-script behaviour A', async () => {
  const myScript = await myScriptWithLibVersionCached()

  assert.ok(myScript.behaviourASucceeds())
})

test('my-script behaviour B', async () => {
  const myScript = await myScriptWithLibVersionCached()

  assert.ok(myScript.behaviourBSucceeds())
})

There may be other ways to optimise and simplify. ava and node:test both support this 'beforeEach' call which could be included in your test formula

const globalImports = {}

test.beforeEach(async () => {
  globalImports.myScript = await myScriptWithLibVersion()
})

from esmock.

yumauri avatar yumauri commented on June 11, 2024

Ok, I got it, thank you for explanations.
I'll look at quibble as well, not sure I saw it before.

from esmock.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.