thlorenz / proxyquireify

browserify >= v2 version of proxyquire. Mocks out browserify's require to allow stubbing out dependencies while testing.
MIT License
152 stars 24 forks source link

Cannot mock non-exisiting module #11

Closed ds82 closed 10 years ago

ds82 commented 10 years ago

Hi,

it seems that it is not possible to mock a module that does not exist. I'm not sure if you say that in the docs with this note:

Note, that unlike in proxquire, there is no option to prevent call thru globally.

(If this means I cannot mock non-existing modules I'm sorry, I'm just not quite sure what you mean with 'globally')

I added a littl' unit test to prove it:

test('\n# module with a not-existing dependency', function (t) {
  var foo = proxyquire('../fixtures/missingDep', {
    './notHere':{
        fn: function() { return 'Iam a mock!' }
      , '@noCallThru': true
    }
    , '@noCallThru': true
  })

  t.equal(foo.fn(), 'Iam a mock!');
  t.end()
})

missingDep:

var missingModule = require('./notHere');

module.exports = {
  fn: function() {
    return 'Iam a module that requires something thats not here';
  }
};

Test runs fine if 'notHere.js' exists (even if it is empty). If I delete it, the test fails.

thlorenz commented 10 years ago

Yeah, that doesn't work currently with proxyquireify, only with proxyquire. You'd need to tell browserify to not look for it.

One trick is to use the browser field similarly to:

{
  "browser": {
     "./path/to/notHere.js": "./path/to/emtpyfile.js"
  }
}

The other option to look into is browserify-swap which allows you to swap modules out for testing.

It'd help if you cold elaborate on why you need this feature, i.e. what are you trying to do and why. You could also push up a sample case to github that'll help me and others understand and help.

ds82 commented 10 years ago

Thanks for your kind response and your offer to help!

The project I'am working on runs on different "platforms" which require different implementations of some (of my) modules. Our build-server builds a separate browserify module for each platform with a custom configuration. In this configuration I kind of 'inject' the module for the corresponding platform using browserify's require-expose option.

For e.g.: In the source tree, the platform specific modules are in separate files:

somemodule/platformA/script.js somemodule/platformB/script.js somemodule/platformC/script.js

In the modules that require the above module I do this: [...] var some = require('somemodule'); [...]

.. and then I use browserify to inject the platform specific module for the build: { [...] require: [['../path/somemodule/platformA/script', { expose: 'somemodule' }]], [...] }

In my tests I want to mock 'somemodule' .. and thats the problem. But of cause I can use the trick you mentioned or just use require/expose methods in my tests, too (and then inject an empty module). I just wanted to keep my test-setup as simple as possible - but providing a config for injected modules is acceptable.

thlorenz commented 10 years ago

Sounds like the above mentioned browserify-swap is more what you want. proxyquireify is designed for testing instead of swapping modules depending on environment. Sorry it can't provide exactly what you need, but your's is a very special use case. Feel free to fork proxyquireify in order to add this feature unless you find another way.

Thanks.

ezequiel commented 9 years ago

@thlorenz Does this functionality (mocking non-existent modules) exist in today's version of proxyquireify? According to my tests-- no.