thlorenz / proxyquireify

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

TypeError: undefined is not a function #6

Closed weilu closed 10 years ago

weilu commented 10 years ago
// index.js
var crypto = require('crypto')

module.exports = {
  randomBytes: crypto.randomBytes
}
// test/index.js
var proxyquire = require('proxyquireify')(require)
// var proxyquire = require('proxyquire') //proxyquire works
var stubs = {
  'crypto': {
    randomBytes: function(size){
      var buffer = new Buffer(size)
      buffer.fill(0)
      return buffer
    }
  }
}
var assert = require('assert')
var randomBytes = proxyquire('../', stubs).randomBytes

describe('randomBytes', function(){
  it('works', function(){
    assert.equal(randomBytes(1).toString('hex'), '00')
  })
})
// build.js
var proxyquire = require('proxyquireify');
var fs = require('fs')

proxyquire.browserify()
.require(require.resolve('./test/index.js'), {entry: true})
.bundle()
.pipe(fs.createWriteStream(__dirname + '/test/bundle.js'));
node build.js && mocha test/bundle.js 

/Users/weilu/Workspace/test-proxyquirify/test/bundle.js:3043
d requires to make browserify include dependencies in the bundle */;require('.
                                                                    ^
TypeError: undefined is not a function

If I use proxyquire without browserify and proxyquireify (uncomment line 2 in test/index.js), my test passes.

I've put together the code above in a repo: https://github.com/weilu/test-proxyquireify The error can be reproduced by running npm test

thlorenz commented 10 years ago

There is no way proxyquire works for browser code since it relies on require extensions`.

Do these tests run client side or server side?

weilu commented 10 years ago

The tests run on server side after browserifying through build.js

weilu commented 10 years ago

I dug a bit deeper and believe it's a variable hoisting issue. Here's a snippet of the browserified code:

},{}],17:[function(require,module,exports){
(function (Buffer){
/* proxyquireify injected requires to make browserify include dependencies in the bundle */;
require('../');
/*proxyquireify override */;
var require_ = require;
var require = require('proxyquireify').proxy(require_);

The undefined is not a function error was thrown from the line require('../'); because require is redeclared and assigned later which causes it to become undefined before the assignment. Dropping the var on this line fixed it for me. I wanted to PR it but couldn't run the client side tests therefore couldn't add tests for it. @thlorenz thoughts?

thlorenz commented 10 years ago

Could you please try to see if that is fixed in the latest version (some major changes, so hopefully they addressed your changes).

weilu commented 10 years ago

I tried @jhiesey's branch. It fixes the issue reported here.