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

Usage with mocha #39

Closed
ColCh opened this issue Feb 5, 2015 · 5 comments
Closed

Usage with mocha #39

ColCh opened this issue Feb 5, 2015 · 5 comments

Comments

@ColCh
Copy link

ColCh commented Feb 5, 2015

I have small test case...
I want to replace some methon on global variable which is Sequelize model:

var models  = ... // sequelize models
var Product = models.Product;
    describe('read', function () {
      var modelsActions = rewire(projectPath + 'lib/excel/modelsActions.js');

      var products = [{name: "Some product from DB"}];
      var fakeFindAll = sinon.stub().returns(Promise.resolve(products));

      var revertRewire;

      before(function () {
        revertRewire = modelsActions.__set__('Product.findAll', fakeFindAll);
      });

      after(function () {
        revertRewire();
      });

      it('should load all products from DB', function () {
        modelsActions.read();
        fakeFindAll.should.be.called;
      });

      it('should order by ascending ID', function () {
        modelsActions.read();
        fakeFindAll.should.be.calledWith(sinon.match({order: 'id ASC'}));
      });

      it('should load without limit', function () {
        modelsActions.read();
        fakeFindAll.should.be.calledWith(sinon.match({limit: 0}));
      });
    });

But it throws:

    main functional
      read
        ✓ should load all products from DB
        ✓ should order by ascending ID
        ✓ should load without limit
        1) "after all" hook

  4 passing (314ms)
  9 pending
  1 failing

  1) Model Actions tests main functional read "after all" hook:
     TypeError: Cannot read property 'findAll' of undefined
      at Object.eval (eval at __set__ (/srv/lib/excel/modelsActions.js:273:19), <anonymous>:1:40)
      at Object.__set__ (/srv/lib/excel/modelsActions.js:273:5)
      at /srv/lib/excel/modelsActions.js:276:24
      at Context.<anonymous> (/srv/test/lib/excel/modelsActions.js:149:9)
      at callFn (/usr/local/lib/node_modules/mocha/lib/runnable.js:251:21)
      at Hook.Runnable.run (/usr/local/lib/node_modules/mocha/lib/runnable.js:244:7)
      at next (/usr/local/lib/node_modules/mocha/lib/runner.js:259:10)
      at Immediate._onImmediate (/usr/local/lib/node_modules/mocha/lib/runner.js:276:5)
      at processImmediate [as _immediateCallback] (timers.js:349:17)

If I get variable and then set it back, everything works like expected.

      var oldProductFindAll;

      before(function () {
        var oldProductFindAll = modelsActions.__get__('Product.findAll');
        modelsActions.__set__('Product.findAll', fakeFindAll);
      });

      after(function () {
        modelsActions.__set__('Product.findAll', oldProductFindAll);
      });

It's a bug or I'm using it wrong?

@ColCh
Copy link
Author

ColCh commented Feb 5, 2015

Any ideas how revert is now working?

Hm, wrote small workaroud for a while:

var rewireReplace = function (module, replaces) {
  var reverts = {};

  Object.keys(replaces).forEach(function (key) {
    reverts[key] = module.__get__(key);
    module.__set__(key, replaces[key]);
  });

  return function revert () {
    Object.keys(reverts).forEach(function (key) {
      module.__set__(key, reverts[key]);
    });
  };
};

Usage:

      var revertRewire;

      before(function () {
        revertRewire = rewireReplace(modelsActions, {
          'Product.findAll': fakeFindAll
        });
      });

      after(function () {
        revertRewire();
      });

@jhnns jhnns closed this as completed in 75ebdd4 Feb 5, 2015
@jhnns
Copy link
Owner

jhnns commented Feb 5, 2015

Should be fixed with 2.1.5 😀

@ColCh
Copy link
Author

ColCh commented Feb 6, 2015

Thanks.

Partially :)

Works:

      var revertRewire;

      before(function () {
        revertRewire = modelsActions.__set__('Product.findAll', fakeFindAll);
      });

      after(function () {
        revertRewire();
      });

Also this way it works too (I think it's a nice way to inject mocks):

      var revertRewire;

      before(function () {
        revertRewire = modelsActions.__set__({
          Product: {
            findAll: fakeFindAll
          }
        });
      });

      after(function () {
        revertRewire();
      });

And this - nope:

      var revertRewire;

      before(function () {
        revertRewire = modelsActions.__set__({
          'Product.findAll': fakeFindAll
        });
      });

      after(function () {
        revertRewire();
      });

So, I really like this way

        revertRewire = modelsActions.__set__({
          Product: {
            findAll: fakeFindAll
          }

jhnns added a commit that referenced this issue Feb 9, 2015
@jhnns
Copy link
Owner

jhnns commented Feb 9, 2015

        revertRewire = modelsActions.__set__({
          'Product.findAll': fakeFindAll
        });

This syntax was never intended to work 😁. But it is possible to implement, so I added it with v2.2.0

@ColCh
Copy link
Author

ColCh commented Feb 10, 2015

Thank you! 👍

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