Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

proxyquire not stubbing module function #236

Closed
samuela opened this issue Jan 30, 2019 · 2 comments
Closed

proxyquire not stubbing module function #236

samuela opened this issue Jan 30, 2019 · 2 comments

Comments

@samuela
Copy link

samuela commented Jan 30, 2019

Check out this PR (oclif/config#70) at this commit (oclif/config@eb4b915). The ts-node.ts module looks something like:

function registerTSNode(root: string) {
  const tsconfig = loadTSConfig(root)
}

function loadTSConfig(root: string): TSConfig | undefined {
  console.log('loadTSConfig unstubbed')
  // function to be stubbed...
}

export function tsPath(root: string, orig: string | undefined): string | undefined {
  registerTSNode(root)
}

and I'm requiring it with proxyquire as follows:

const stubLoader = (_: any) => {
  console.log('loadTSConfig proxyquire')
  return config
}
const tsNodePlugin = proxyquire('../src/ts-node', {'loadTSConfig': stubLoader})

// This prints "loadTSConfig unstubbed" not "loadTSConfig proxyquire"!
tsNodePlugin.tsPath('poop', 'asdf')

But unfortunately proxyquire is not actually injecting stubLoader into the module as expected.

I've tried:

  • Exporting all of the functions in ts-node.ts
  • Calling tsNodePlugin.registerTSNode, and even tsNodePlugin.loadTSConfig directly
  • Adjusting the stub key: '.loadTSConfig', './loadTSConfig', etc
  • Clearing the cache with delete require.cache[require.resolve('../src/ts-node')]
    all to no avail.
@bendrucker
Copy link
Collaborator

Hi, proxyquire operates on modules, and not by munging your local scope within a module. You can't stub something in the local scope of the module under test. You can stub something that your module under test requires. We believe this is important to maintainable tests.

If your tests can manipulate the local variables of modules under test, there is no isolation between your tests and your source code. Changing an internal function name within your source code should not break tests.

If you'd like to use proxyquire, I'd recommend pulling that function out to its own module. You'll then stub it by its path relative to the module under test, and not its identifier (which is private).

proxyquire('../src/ts-node', {'./load-ts-config': stubLoader})

@samuela
Copy link
Author

samuela commented Jan 30, 2019

Understood, thank you for the quick response.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants