plasticine / inject-loader

💉📦 A Webpack loader for injecting code into modules via their dependencies.
https://www.npmjs.com/package/inject-loader
MIT License
482 stars 47 forks source link

Nested dependencies? #80

Open Wizek opened 3 years ago

Wizek commented 3 years ago

To quote #23:

Hello! In my scenario I have a file a.js requiring b.js which requires c.js I want to mock c.js when I require a.js

Is it possible? So far I was only able to mock c.js if I mock b.js directly...

Thank you!

Has this become possible in the last 4.5 years?

If not, what is advised here? Can this be worked around? Or does a different package have this feature?

Wizek commented 3 years ago

Imagine a scenario like this:

// stuff.js

export const ourFetch = fetch

export const postJson = async (url, payload) => {
  const res = await ourFetch(url, {
    method: 'POST',
    body: JSON.stringify(payload),
    headers: {
      'Content-Type': 'application/json',
    },
  })
  const obj = await res.json()
  return obj
}

export const putJson = async (url, payload) => {
  const res = await ourFetch(url, {
    method: 'PUT',
    body: JSON.stringify(payload),
    headers: {
      'Content-Type': 'application/json',
    },
  })
  const obj = await res.json()
  return obj
}

export const getJson = async (url) => {
  const res = await ourFetch(url)
  const obj = await res.json()
  return obj
}

export const deleteReq = async (url) => {
  const res = await ourFetch(url, {
    method: 'DELETE',
  })
  return res
}

export const apiBase = "/api"

export const apiReadStuffs  = () => getJson(`${apiBase}/stuff`)
export const apiReadStuff   = id => getJson(`${apiBase}/stuff/${id}`)
export const apiDeleteStuff = id => deleteReq(`${apiBase}/stuff/${id}`)
export const apiCreateStuff = pl => postJson(`${apiBase}/stuff/`, pl)
export const apiUpdateStuff = (id, pl) => putJson(`${apiBase}/stuff/${id}`, pl)

If we want to run tests that involve these api* functions, it would be nice if we could mock ourFetch directly like this:

const injector = require('inject-loader!somethingThatUsesApiCalls.js')
const sth = injector({
  './stuff.js': {ourFetch: () => {json: () => ({ok: 1})}}
})