Giter VIP home page Giter VIP logo

mockery's People

Contributors

bengl avatar carlosvillademor avatar davglass avatar mfncooper avatar redonkulus avatar roblg avatar starefossen avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mockery's Issues

more cross-test issues

A test requires the module I have under test before the test that enables mocking runs. This means my mocks aren't applied, depending on the order that my test suite runs. Rather brittle. How can I get around this?

My fix at the moment is to forcefully delete the required item directly from the require.cache but that seems ugly. I wish there was a way to always 'hot require' specified paths.

enabling specific mocks per test

Hi, I know this has been covered a bit before but I don't seem to be able to do this in a reasonable manner.
What I would like is this.
I have a mut ( module under test ). It takes a dependency on gesPromise. I mock gesPromise with gesPromiseMock. the module is a function which takes args my mock is a function that takes setup args then return a function the stub function. So here is my mock and how i use it.

module.exports = function (result){
    return function(conn, name, skipTake) {
        var data = JSON.stringify({eventName: "someEvent"});
        var newVar = !result ? {
            Status: 'OK',
            NextEventNumber:3,
            Events: [{Event:{EventName:'someEvent',Data: data}},{Event:{EventName:'someEvent',Data: data}},{Event:{EventName:'someEvent',Data: data}}],
            IsEndOfStream: false
        } : result;
        return Promise.resolve(newVar);
    }
};
        var result = {
            Status: 'StreamNotFound',
            NextEventNumber: 500,
            Events: [{}],
            IsEndOfStream: false
        };
        mockery.registerMock('./readStreamEventsForwardPromise', readStreamEventsForwardPromiseMock(result))

so what I would like is to be able to change the "results" for different tests. The only way I've been able to do that so far is with the following set. Note that I must use completely different describe setups.

describe('getEventStoreRepository', function() {
    var mut;
    before(function(){
        mockery.enable({
            warnOnReplace: false,
            warnOnUnregistered: false
        });
        var result = {
            Status: 'StreamNotFound',
            NextEventNumber: 500,
            Events: [{}],
            IsEndOfStream: false
        };
        mockery.registerAllowable('../src/ges/gesRepository', true);
        mockery.registerMock('ges-client', connection);
        mockery.registerMock('./gesPromise', {readStreamEventsForwardPromise: readStreamEventsForwardPromiseMock(result), appendToStreamPromise:appendToStreamPromiseMock} );
    });
describe('#getById_return bad results', function() {
        context('when calling getById with proper args but stream deleted', function (){
            it('should throw proper error', function () {
                mut = require('../src/ges/gesRepository')();
                var id = uuid.v1();
                var streamName = streamNameStrategy(TestAgg.aggregateName(),id);
                var byId = mut.getById(TestAgg, id, 0);
                return byId.must.reject.error(Error, 'Aggregate Deleted: '+streamName);
            })
        });
    });

    after(function () {
        mockery.deregisterAll();
        mockery.disable();
    });
});

now if I do another setup for a test exactly like the above but with different result data it will work.
this is a lot of ceremony for each test. Is there any way to do it for each test rather than a whole setup?
thanks,
r
sorry about all the implementation details.

How to Spy On a Mocked Thing?

Hello! Thanks for making this nice module! I'm wondering how I can "spy on" a mocked module so that I can make assertions about how it was called.

Suppose I am trying to mock the request-promise libary which is normally called with request.get, here's my mockery code:

mockery.registerMock('request-promise', {
      get: () => {
        return {
          statusCode: 200,
          body: {
            foo: "barracuda"
          },
        };
      },
    });

    mockery.enable({
      warnOnReplace: false,
      warnOnUnregistered: false,
    });

I would like to assert that request.get was called with the correct params. I tried setting up a sinon spy as usual, it didn't seem to work. :/

requestSpy = sinon.spy(request, 'get')

Is there any recommended way to do this with mockery?

Thanks! 🙏

ResetCache to certain files

I would like to be a method like: resetCache(), but it will unload only the specified file.

When you call resetCache, you have a big performance issue...

Not mocking anything (Mocha/Chai/ES6)

Hi,

I'm quite new to JS unit testing (I'm more of a PHP backend developper).
I recently worked on an Express API, fully written in ES6 (using babel), and wanted to fortify it with some unit tests.

I managed to setup Mocha & Chai to work like a charm on my "standard" tests, but when it comes to mocks, I can't seem to figure it out. I've tried quite everything I had in mind, but still can't get it to work.

I first needed to mock a class within the elastic search module, and I couldn't get it to work. So I tried it in some lightweight/sandbox files.

I have lib.js (the module I want to mock)

export default {
    val: () => true
};

Then script.js (the module I want to test)

import lib from './lib';

export default {
    exec: () => {
        const val = lib.val();
        if (val) {
            console.warn('Not mocked');
        } else {
            console.log('Mocked !');
        }

        return val;
    }
}

And the full test file (script.spec.js, in the exact same folder as the two others)

import chai from 'chai';
import sinon from 'sinon';
import sinonChai from 'sinon-chai';

let should = chai.should();
chai.use(sinonChai);

import mockery from 'mockery';
let libMock = {
    val: sinon.stub()
};

libMock.val.returns(false);

mockery.registerSubstitute('./lib', libMock);
mockery.enable({
    warnOnUnregistered: false
});

import script from './script'

describe('script', () => {
    describe('can mock a lib that', () => {
        it('should return false instead of true', () => {
            script.exec().should.equal(false);
            libMock.val.should.have.been.calledOnce();
        });
    })
});

And its output (run in IntelliJ Idea) :

Not mocked

AssertionError: expected true to equal false
Expected :false
Actual   :true
 <Click to see difference>

    at Context.<anonymous> (script.spec.js:25:34)

Process finished with exit code 1

Dependencies :

  • mocha: 2.3.4
  • mockery: 1.4.0

test/mocha.opts :

--require babel-core/register
--require mocha
--require chai-as-promised

Issue with webpack

ERROR in ./~/mockery/mockery.js
Module not found: Error: Cannot resolve module 'module' in /private/var/www/coders51/mta-components/node_modules/mockery
 @ ./~/mockery/mockery.js 39:8-25

Any ideas? Thanks!

`registerMock` should throw an error if the module being mocked has already been required

So I know the proper way to use registerMock is to call it before requiring modules in the unit test. However this a little unintuitive for developers unfamiliar with mockery, and it would make a lot more sense if there was an option to throw an error if the module being mocked has already been required in an earlier statement (say, inside beforeEach). If this sounds useful, I can submit a PR.

Unexpected token import

I have no idea what the source of this error is. I'm hoping you can at least point me in the right direction.

import { expect } from 'chai';
import * as mockery from 'mockery';
import * as sinon from 'sinon';
import Spotify from '../src/lib/Spotify';
import ActionTypes from '../src/lib/ActionTypes';

describe('Player', () => {

  let player, spotifyStub;

  before(() => {
    mockery.enable({
      warnOnReplace: true,
      warnOnUnregistered: true,
      useCleanCache: true
    });

    spotifyStub = sinon.createStubInstance(Spotify);
    spotifyStub.emit.restore();

    // replace the module `Spotify` with a stub object
    mockery.registerMock('./Spotify', spotifyStub);

    debugger;

    player = require('../src/lib/Player'); // errors
  });

  after(() => {
    mockery.disable();
  });

  it('should retry connection on spotify error', (done) => {
    ...
  })

});

Errors with:

1) Player "before all" hook:
   xxx/src/lib/player.js:1
(function (exports, require, module, __filename, __dirname, process, global) { import Spotify from './Spotify';
                                                                             ^^^^^^
SyntaxError: Unexpected token import
    at Object.exports.runInThisContext (vm.js:76:16)
    at Module._compile (module.js:513:28)
    at Object.Module._extensions..js (module.js:550:10)
    at Module.load (module.js:458:32)
    at tryModuleLoad (module.js:417:12)
    at Module._load (module.js:409:3)
    at Function.hookedLoader [as _load] (xxx/node_modules/mockery/mockery.js:111:12)
    at Module.require (module.js:468:17)
    at require (internal/module.js:20:19)
    at Context.before (xxx/app/spec/player.spec.ts:26:14)
    at runCallback (timers.js:566:20)
    at tryOnImmediate (timers.js:546:5)
    at processImmediate [as _immediateCallback] (timers.js:525:5)

Where Player.js starts with an import...

import Spotify from './Spotify';
class Player {
...

Mocking across tests

Hi Martin,

I don't think this is necessarily an issue with Mockery, but I'm having a hard time finding a good solution for this problem. The problem is that if I run one test that requires a real module, and then run another that mocks that same module, the mocked version fails (the reverse is also seems to be true but I'm having a hard time proving it). This is only a problem when a test runner loads all the test files at once, which caches the require paths and mockery gets bypassed (or something).

I've simplified the problem into a standalone git repo here:

https://github.com/BryanDonovan/nodejs-mock-test

If you have a chance to take a look, I'd really appreciate it. It might just be something obvious that I'm doing wrong.

Thanks,
Bryan

Bad cache restore for addon modules

Mockery's restoration of the cache on disable() seems inadequate for addon modules.

I'm using Windows 7, SP2, 64bit, node 0.12.4 (32 bit) and Mockery 1.4.0.

Clone node-addon-examples and add a couple of javascript files to the root folder of the first example: node-addon-examples\1_hello_world\node_0.12.

File 1: tock.js (12 lines)

var mockery = require('mockery');
// useCleanCache: true is necessary to reproduce the problem
mockery.enable(
{useCleanCache: true}
);
// registerSubstitute() is a workaround for the problem.
// mockery.registerSubstitute('./build/Release/hello.node', './tick.js');
var addon = require('./build/Release/hello.node');
console.log(addon.hello());
mockery.disable();
var addon2 = require('./build/Release/hello.node');
console.log(addon2.hello());

File 2: tick.js (1 line)

module.exports.hello = function () { return "world";};

In a command window, cd to the root folder and run the following commands.

npm install
npm install mockery
node tock.js

The output was the following.

D:\Builds\node-addon-examples\1_hello_world\node_0.12>node tock.js
WARNING: loading non-allowed module: ./build/Release/hello.node
world
module.js:355
    Module._extensions[extension](this, filename);
                           ^
Error: Module did not self-register.
    at Error (native)
    at Module.load (module.js:355:32)
    at Function.Module._load (module.js:310:12)
    at Module.require (module.js:365:17)
    at require (module.js:384:17)
    at Object.<anonymous> (D:\Builds\node-addon-examples\1_hello_world\node_0.12\tock.js:11:14)
    at Module._compile (module.js:460:26)
    at Object.Module._extensions..js (module.js:478:10)
    at Module.load (module.js:355:32)
    at Function.Module._load (module.js:310:12)

If we alter the code to turn off useCleanCache or if we uncomment the line to registerSubstitute() and rerun, then it runs without error.

I tried a similar test on other examples in this repo of addon examples, with similar results.

Support require.resolve to not return the path.

Ideally, we would be able to also have require.resolve return something different than the actual implementation.

I.e. I'm trying to check for the absence of a module. And in my code, after mocking via mockery.registerMock('koa-bodyparser', null);
the require.resolve('koa-bodyparser') still returns the actual path, where require('koa-bodyparser') returns null.

To allow the best of both ways, this could be an config option to mockery.

Thanks!

Error: Module did not self register

I get the following error, when mockery is enabled:

mockery.enable({
            warnOnReplace: false,
            warnOnUnregistered: false,
            useCleanCache: true
        });
[Error: Module did not self-register.]
{ [Error: Cannot find module './build/default/DTraceProviderBindings'] code: 'MODULE_NOT_FOUND' }
{ [Error: Cannot find module './build/Debug/DTraceProviderBindings'] code: 'MODULE_NOT_FOUND' }

My test cases work fine. How do I get rid of these errors?

Mockery doesn't seem to be doing anything

views.js

controllers = require '../../modules/fixture/controllers.js'
exports.custom = (db) ->
  (req, res) ->
    controllers.custom req.body
      , (result) ->
        res.json result : result
      , (error) ->
        res.json 400, error : error

test.js

mockery = require "mockery"

exports.tests = (app, db, config) ->
  describe '#routes', ->
    describe '/fixture/custom', ->
      it 'should return status 400 if no request body was provided', (done) ->
        request app
          .post '/fixture/custom'
          .send
            body :
              players : []
          .expect 400, done

  describe '#views', ->
    describe '#custom', ->
      controller =
        custom : (body, success_callback, error_callback) ->
          console.log "###MOCK CONTROLLER BODY: #{req}"
          if body
            success_callback 'result'
          else
            error_callback 'error'
      mockery.enable()
      mockery.registerAllowable '../../modules/fixture/controllers.js', true
      mockery.registerMock '../../modules/fixture/controllers.js', controller

      it 'should return json keyed by result on success callback', (done) ->
        req =
          body : true
        res.json = (response) ->
          response.result.should.eql 'result'
          done()
        custom req, res

I get the error TypeError: Cannot read property 'should' of undefined which I have confirmed is due to my mock not getting registered as I'd like.

I'm thinking the problem is that require(../../modules/fixture/controllers.js) is happening before test.tests(app, db, config) is called, and so the require cache is already created.

Shouldn't mockery.registerAllowable('../../modules/fixture/controllers.js', true) allow me to override already required modules? I require quite a lot of switching between real and mock modules throughout many tests, so I'd prefer to be able to register mocks "just in time" rather than all at the beginning, for instance before instantiating my express app. Is this possible?

How to verify whether a call to require actually happened?

I am using mockery to mock some modules. Now I have a special case where I just want to know whether a call to require with a specific module happened or not. As this has no side-effects that are visible from the outside, I can not test any specific behavior.

Basically I just need to know if require was called with parameter foo or not.

How could I test this?

Mockery.resetCache() doesn't work where Mockery.deregisterMock() does

tests.js

mockery = require "mockery"
mockery.enable
  warnOnUnregistered : false
  warnOnReplace : true
  useCleanCache : true

Later on I mock controllers.js and this works fine, with the test outputting MOCK CONTROLLER as expected.

  describe '#views', ->
    describe '#custom', ->
      controller =
        custom : (body, success_callback, error_callback) ->
          console.log 'MOCK CONTROLLER'
          if body
            success_callback 'result'
          else
            error_callback 'error'
      mockery.registerMock '../../modules/fixture/controllers.js', controller
      views = require '../../modules/fixture/views.js'
      custom = views.custom null

      it 'should return json keyed by result on success callback', (done) ->
        req =
          body : true
        res.json = (response) ->
          response.result.should.eql 'result'
          done()
        custom req, res

Then when I come to testing a different component, I want to run mockery.resetCache() before mocking other modules:

  describe '#controller', ->
    describe '#custom', ->
      body =
        players : []
      # Mock the launcher.
      launcher =
        launch : (players, map, player_spectate, success_callback, error_callback) ->
          if map? && map == 1
            success_callback 'success'
          else
            error_callback [
              code : 1
            ]

      # THIS DOESN'T WORK:
      mockery.resetCache()
      # THIS WORKS:
      mockery.deregisterMock '../../modules/fixture/controllers.js'

      mockery.registerMock '../../modules/launcher/controllers.js', launcher
      custom = require '../../modules/fixture/controllers.js'
      .custom

      it 'should call the error callback if no players selected', (done) ->
        custom body
          , () ->
            return
          , (err) ->
            err.should.containEql '6 players'
            done()

If I rely on mockery.resetCache() I still end up with output of MOCK CONTROLLER. If I use mockery.deregisterMock however I get the desired effect.

registerMock() does not work when code is ran with jest?

Below code does not look work at all,
I do not think I've made any mistakes here, but console still logs out the return from from original aws-sdk require call, not newly mocked {}

test.spec.js

require('jest');
const mockery = require('mockery');

describe('test', () => {
  beforeAll(() => {
    mockery.enable({
      warnOnReplace: false,
      warnOnUnregistered: false
    });
    mockery.registerMock('aws-sdk', {});
    const aws = require('aws-sdk');
    console.log(aws);
  });

  it('', () => {
    expect(true).toBeTruthy();
  });
});

strangely, this does work if

  1. I do this for 'fs' module, not the 'aws-sdk' (which isn't native module of node)
  2. Run this just with a node after stripping all jest related code (which means running the test with jest makes this code fail)

Tests

unit tests would be great.

As a sidenote it would be nice to have an examples folder or some pointers to projects that use mockery.

Fail on unregistered require

Would it be possible to add a config that will fail the run (i.e. throw an Error) if a module that is not registered either as a mock or as allowed is loaded? The warnOnUnregistered log output is very easy to miss if you want to be certain that you are not loading something by mistake, especially when the test suite is large.

Something like:
mockery.enable({ throwOnUnregistered: true });

Destructuring Bug or am I doing this wrong?

Just trying to use some destructing.

If I have.

// add.js
const {a, b} = require('./numbers.js');

const add = () => a + b;

module.exports = {add};

The test fails when I go to mock numbers. However, if I rewrite the module to not have destructuring...

const numbers = require('./numbers.js');

const add = () => numbers.a + numbers.b;

module.exports = {add};

My test will pass. It's kinda annoying actually. Is there anything I can do about this? I thought the mockery was suppose to overwrite the require. Or is mockery simply just passing the object around and with destructuring, new objects are created rather than references?

Release version

Please release a version of this tool, so I can tag version in package.json.

registerMock never mocks

What is it that I'm missing?

test.js

  setup(function() {
    mock.enable();
  });

  teardown(function() {
    mock.disable();
  });

  ....

  test('should return bad request when provider id is unknown', function(done) {

    var db = Helpers.database();
    db.getItem = function() {
      return function(data, cb) {
        console.log('burp');
        cb(null, {one: 1});
      };
    };

    mock.registerMock('../database', function() {console.log('mocked');return db;});

    request(app).post('/link-players')
      .set('authorization', Helpers.fakeAuthorizationHeader())
      .send({provider: {id: 'test', metadata: {deviceID: '1', username: 'username'}}})
      .expect(400, err(status[400], 'Provider unknown'))
      .end(function(err) {
        mock.deregisterMock('../database');
        done(err);
      });
  });

file-requiring-module-i-want-to-mock.js

'use strict';
var database = require('../database'); // <-----
var xtend = require('xtend');


module.exports = function attachDatabase(options) {
  return function middleware(req, res, next) {
    options = options == null ? {} : options;
    var token = (req.player != null && req.player.accessToken != null) ? req.player.accessToken : null;
    if (token != null) {
      options = xtend(options, {sessionToken: token});
    }
    req.db = database(options);
    console.log(JSON.stringify(req.db)); // <---- is always the unmocked module
    next();
  };
};

useCleanCache has some unexpected side effects

using Yadda together mockery has some unexpected side effects.

# goes wrong
Yadda = require 'yadda'
mockery.enable useCleanCache: true

# works ok
mockery.enable useCleanCache: true
Yadda = require 'yadda'

Yadda behaves differently, see also acuminous/yadda#34
There is no difference if modules are actually mocked or not.

Can't get mockery to work

File: lib/movie.js

var Movie = module.exports = {
  text: 'newmoon'
}

File: tests/movie.js

describe('movie test', function(){
  it('should have mock text', function(){
    var movieMock = {
      text: 'twilight'
    };
    mockery.registerMock('movie', movieMock);

    var movie = require('movie');
    movie.text.should.equal('twilight');
  });
});

Command:

$ NODE_PATH=lib mocha -R spec tests

Output:

movie test
    1) should have mock text


  0 passing (10 ms)
  1 failing

  1) movie test should have mock text:

      actual(red) expected(green)

      twilight(green) newmoon(red)

What have I done wrong?

better handling of relative paths

An example:

// src/dependency.js
throw new Error("Shouldn't be required!");


// src/mocked.js
require('./dependency');


// test/mockery_test.js
var mockery = require('mockery');
mockery.enable();
mockery.registerMock('../src/dependency', {});
var mocked = require('../src/mocked');

Running node test/mockery_test.js will throw the Error. It would be great if registerMock() recognized paths as being relative to the test file (where the mock is coming from), rather than relative to the file that will require them. Does that make sense?

Mock code in another module

I want to mock Amazon AWS S3 getObject

The code I want to test is the following one: Its in helper.js

var AWS = require('aws-sdk');
var s3 = new AWS.S3();

exports.get_data_and_callback = function(callback, extra){
  s3.getObject( {Bucket: SRC_BUCKET, Key: SRC_KEY},
    function (err, data) {
      if (err != null) {
        console.log("Couldn't retrieve object: " + err);
      }else{
        console.log("Loaded " + data.ContentLength + " bytes");

        callback(data, extra);
     }
  });
}

In test/helper_test.js I wrote a test that should mock the module AWS

var assert = require('assert');
var mockery = require('mockery');

describe("helper", function() {

  it('loads and returns data from S3 to a callback', function(){
     mockery.enable();

    var fakeaws = {
      S3: function(){
          return {
            getObject: function(params, callback){
               callback(null, "hello")
             }
         }
       }
     }
    mockery.registerSubstitute('aws-sdk', fakeaws);

    function replace_function(err, data){
      console.log(data);
    }

     require('../helper.js').get_data_and_callback(replace_function, null);

  });
});

When I require AWS in the Test-File test/helper_test.js like this:

aws = require('aws-sdk');
s3 = new aws.S3;
s3.getObject(replace_function)

Then my code works, it prints out hello.

BUT the execution of require('../helper.js').get_data_and_callback(replace_function, null);

Doesn't work like expected, AWS stays the same its not replaced with my fakeaws. What do I wrong? Do you maybe have other solutions to replace S3? Thanks

interactions between tests running in mocha

I have a large suite of independent tests that all get run in a single process by mocha. It turns out that different mockery mocks are used in different test cases and this produces a situation where the order that the tests run causes problems since the first mock will still be loaded and cached when the second test runs that uses the same module. (I'm sure that was as clear as mud).

It seems to me that a possible solution to this would be to have the behavior of mockery.registerAllowable(module, true) get run on every module that had a registerMock called on it when deregisterAll gets called. Would that work?

registerMock allow regexp as mod parameter

We use mockery also to mock requires on css, svg and all other files which we include using webpack loaders.
It's more faster than precompile tests with webpack (and also there are a lot of issues using webpack with jsdom together).
So we write something like this

mockery.registerMock('./MayBeInput.scss', {});
mockery.registerMock('./button.scss', {});
...etc

but we want this

mockery.registerMock(/\.scss$/, {});

if I create pull request allowing using regexp, do you accept it?

Unable to effectively deregisterMock

In a beforeEach block I am creating and registering a mock:

beforeEach ->
    knife = nodemock.mock()
    knife.counter = (counter += 1)
    console.log("made knife " + knife.counter)
    mockery.registerMock('../../knife', knife);

And unregistering it in afterEach:

afterEach ->
    mockery.deregisterMock('../../knife');

This mock is loaded by the code under test and executed. When the code under test executes a function on the mock, it prints the value of knife.counter so that I can see which instance it is invoking.

The problem I see is that even though beforeEach and afterEach is registering a new mock for each test, the code under test is invoking on the same instance (instance 1). Therefore the mock receives unexpected additional calls compared to the expectation and the test fails.

How to mock .png of .jpg files

How to mock .png of .jpg files,

SyntaxError: D:/BFM Mobile/pushAppcenter/node_modules/react-navigation/src/views/assets/back-icon.png: Unexpected character '�' (1:0)

1 | �PNG

useCleanCache: true - leaks memory

Now all modules will be cached in this new clean cache, until you later disable Mockery again. The new cache is temporary, and is discarded when Mockery is disabled.

When loading a module via require, its reference is also pushed to the array under children property of the module where the require function was used.
Even after mockery swaps back the old cache and deletes the reference to the new temporary cache there are still references to all loaded modules in parents Module.children array so the memory used by those modules can't be freed.

Selective clear when useCleanCache is true

There is a missing feature, that when I use useCleanCache: true, I can't specify a file/folder to be excluded from the cleaning, and to remain as a chached module.

The problems is this:
I have a file that creates an in-memory database with bookshelf.js (and a few options setting the connection is to a sqlite db). If I use useCleanCache: true, that file will be "unloaded" and when I require it again in my tests, it will be loaded again.
The result of this, will be that I will have an unlodaded in-memory database and a new in-memory database.

Notes:
I know there is a discussion if I should or shouldn't test with a db or not. I know it's not the best practice to do it, because it won't be a real unit test, but I would like to in this case. Also, setting up a real db for testing would make the testing slower. I don't want to enter in this discusion right now :D

The solution:
Add a new option: remainingCache: [RegExp] which will contain an array of RegExps, and will be used only if useCleanCache: true. This will change the override of m._cache = {} with an object filled with the original modules that the file name matched any of the RegExps.

I will make a PR with this if you are ok!

Made a fork, would like to merge if possible and/or become a contributor

I forked mockery to cspotcode/mockery-next. (I know, very creative naming!) I liked mockery's API and needed it for some tests at work, but also wanted support for resolving relative paths. I've added that feature and fixed a few other things. It's on npm.

I'd like to merge back into mockery if possible; no sense having extra forks floating around. However, I've made some breaking changes. Any chance for a 2.0 release and/or can I become a contributor to mockery?

Breaking changes

  • Properly resolves relative module paths. Breaking change. Requires all mocked / substituted modules to exist. Otherwise, path resolution fails at registration-time. (Based on @Kubas's PR)

Enhancements

  • Can register null substitutions and mockery will pretend the module doesn't exist. For example: mockery.registerSubstitute('some-optional-module', null);

Bugfixes:

  • Doesn't break when you require('mockery') while useCleanCache is enabled.
  • Substitute modules can have falsey exports.

Allow all option

So that no warnings are produced for any non-mocked module. maybe .registerAllowable() should allow all modules if no module names are passed to it?

Mockery with Babel transpiled ES6 modules gives lots of warnings

When using Mockery to mock out dependencies of modules that are written in ES6 using Babel, there are a number of core Babel modules that get required automatically that need to be marked as allowed to avoid getting warnings.

The example I've found so far is using ES6 classes. When I use Mockery to mock out the dependencies of this module I still get:

WARNING: loading non-allowed module: babel-runtime/helpers/create-class
WARNING: loading non-allowed module: babel-runtime/core-js/object/define-property
WARNING: loading non-allowed module: core-js/library/fn/object/define-property
WARNING: loading non-allowed module: ../../modules/$
WARNING: loading non-allowed module: babel-runtime/helpers/class-call-check
WARNING: loading non-allowed module: babel-runtime/helpers/interop-require-default

I suspect there will be other core imports as well should other parts of ES6/Babel be used.

Uncaught Error: Loader has not been hooked

I'm getting the aforementioned error quite a lot and I'm wondering what general stupidity I'm doing in order to get this error?

I can see a unit-test where this is being exercised, but I don't understand enough about the module-loader internals to understand how I get there.

Any help on the issue is greatly appreciated.

Cleaning mocks cache on disable?

Hi,

I've been having issues on my tests using mockery when I try to register mocks. When I register the mocks with the useCleanCache flag to false my mocks are not being used because some other test is using the module I'm trying to mock, this is expected behaviour as far as I know. The problem is, I'm using useCleanCache set to true to avoid this, and that makes my mocked test pass properly, but because some later test is trying to use the same mocked module, my tests fail because the later test gets the mock. I'm calling mockery.disable and mocker.deregisterAll after the test where I'm using the mock is finished, but apparently the mock is stored on the node module cache so whenever is required again, I get the mock. Is there a way of forcing the cache to be cleaned after mockery is disabled? I thought that was the default behaviour, but it doesn't seem to be working for me?

Thanks!

auto-mock

Add in a new type of mock called autoMock that will require the original module, then smartly stub out all the methods on the module. Putting in place some defaults like:

  • Checking for callbacks being the last argument.
  • Checking if they are EventEmmitter then add some methods

Mocks not recognized

I have this code from:

https://sazzer.github.io/blog/2015/08/20/Unit-Testing-ES6-Modules-Mockery/

I run the test by BABEL_ENV=ES2015 mocha --require babel-register --recursive tests

But i don't get the mocked name in return, instead i get the original name:
AssertionError: 'Hello, Fred' == 'Hello, Graham'

I am using Node: 4.8.4
"mockery": "^2.1.0"
"mocha": "^4.0.1"
"babel-core": "^6.26.0",
"babel-plugin-module-resolver": "^2.7.1",
"babel-plugin-rewire": "^1.1.0",
"babel-plugin-rewire-exports": "^0.2.2",
"babel-preset-env": "^1.6.1",
"babel-register": "^6.26.0",
"babel-template": "^6.26.0",
"babel-types": "^6.26.0",

Normally this should work, when i use boogie666s atom mocha test runner it's working. But strangely when using mocha / npm the mock is not recognized... anyone knows why?

How to just intercept a few require calls.

Hi all,
I'm very new to unit testing, and I'm trying to get familiar with these mock libraries.

I tried to not use the enable function when setup and only do registerMock for some packages, but it's not working for me. I'm guessing the enable function is a must, so is there anyway to just register mock for some module instead of intercepting all of them? I also tried rewire, but apparently it can't intercept any require calls.

mockery and Jasmine

Maybe it's worth mentioning in the readme or wiki that when used with Jasmine mockery needs to be enclosed in a define () and the 'module' should be received as an argument.

The var m = require('module') is simply not working. Maybe it's a Jasmine issue or an undocumented expected behavior.

define(['module'], function (m) {
//var m = require('module') // this call fails even after enclosing it in a define(['module']) {}
.
.
.
return { ... };
}

Simpler API for using mockery

I have been working mockery for some time but since the core API is verbose we have create a wrapper to simplify the use of mockery but i think it would be nicer to have something like that merged in the official repo.

// This is the wrapper we use to mock
function mockRequire(mocks, callback) {
    mockery.enable({
        warnOnUnregistered: mocks.warnOnUnregistered,
        useCleanCache: !mocks.useCache
    });

    Object.keys(mocks).forEach(function (lib) {
        mockery.registerMock(lib, mocks[lib]);
    });

    try {
        callback(mocks);
    } finally {
        mockery.deregisterAll();
        mockery.disable();
    }
}

// This are the tests for this feature
describe('#mockReqire', function () {
    it('mocks some libs', function () {
        var tdMocked;
        var fsMocked;

        mockRequire({
            '../index': 'I am Mocked!',
            'fs': 'I am NOT real!'
        }, function () {
            tdMocked = require('../index');
            fsMocked = require('fs');
        });

        assert.equal(tdMocked, 'I am Mocked!');
        assert.equal(fsMocked, 'I am NOT real!');

        assert.notDeepEqual(tdMocked, require('../index'));
        assert.notDeepEqual(fsMocked, require('fs'));
    });
});

// Usecase Example                                                                                                                                                                        
describe('SomeComponent', function () {      
    var SomeComponent;

    mockRequire({                                                                                                                                                            
        '../services': mockServices,                                                                                                                           
        'api': mockAPI                                                                                                                                                    
    }, function () {                                                                                                                                                         
        SomeComponent = require('../../services/yFinLists/trending_tickers');                                                                                      
    });                                                                                                                                                                   

    it('tests stuff on the component', function () {                                                                                                               
          ...                                               
    });

The advantage is because you can mock several modules at once and there is not need to use before/after hocks. This feature is very useful for the projects I am working and I would be glad to submit a PR.

sub-dependencies from allowed modules throw warnings as "non-allowed"

Similar to #35, when using something like, say express, and registering it as allowable, I get lots of warnings about what isn't allowed. This seems like clutter

WARNING: loading non-allowed module: ./lib/express
WARNING: loading non-allowed module: events
WARNING: loading non-allowed module: merge-descriptors
WARNING: loading non-allowed module: ./application
WARNING: loading non-allowed module: finalhandler
WARNING: loading non-allowed module: debug
WARNING: loading non-allowed module: tty
WARNING: loading non-allowed module: util
WARNING: loading non-allowed module: ./debug
WARNING: loading non-allowed module: ms
WARNING: loading non-allowed module: escape-html
WARNING: loading non-allowed module: on-finished
WARNING: loading non-allowed module: ee-first
WARNING: loading non-allowed module: statuses
WARNING: loading non-allowed module: ./codes.json
WARNING: loading non-allowed module: unpipe
WARNING: loading non-allowed module: ./router
WARNING: loading non-allowed module: ./route
WARNING: loading non-allowed module: debug
WARNING: loading non-allowed module: array-flatten
WARNING: loading non-allowed module: ./layer
WARNING: loading non-allowed module: path-to-regexp
WARNING: loading non-allowed module: debug
WARNING: loading non-allowed module: methods
WARNING: loading non-allowed module: http
WARNING: loading non-allowed module: ./layer
WARNING: loading non-allowed module: methods
WARNING: loading non-allowed module: utils-merge
WARNING: loading non-allowed module: debug
WARNING: loading non-allowed module: depd
WARNING: loading non-allowed module: ./lib/compat
WARNING: loading non-allowed module: buffer
WARNING: loading non-allowed module: events
WARNING: loading non-allowed module: ./lib/compat
WARNING: loading non-allowed module: path
WARNING: loading non-allowed module: array-flatten
WARNING: loading non-allowed module: parseurl
WARNING: loading non-allowed module: url
WARNING: loading non-allowed module: methods
WARNING: loading non-allowed module: ./middleware/init
WARNING: loading non-allowed module: ./middleware/query
WARNING: loading non-allowed module: parseurl
WARNING: loading non-allowed module: qs
WARNING: loading non-allowed module: ./stringify
WARNING: loading non-allowed module: ./utils
WARNING: loading non-allowed module: ./parse
WARNING: loading non-allowed module: ./utils
WARNING: loading non-allowed module: debug
WARNING: loading non-allowed module: ./view
WARNING: loading non-allowed module: debug
WARNING: loading non-allowed module: path
WARNING: loading non-allowed module: fs
WARNING: loading non-allowed module: ./utils
WARNING: loading non-allowed module: content-disposition
WARNING: loading non-allowed module: path
WARNING: loading non-allowed module: content-type
WARNING: loading non-allowed module: depd
WARNING: loading non-allowed module: array-flatten
WARNING: loading non-allowed module: send
WARNING: loading non-allowed module: http-errors
WARNING: loading non-allowed module: setprototypeof
WARNING: loading non-allowed module: statuses
WARNING: loading non-allowed module: ./codes.json
WARNING: loading non-allowed module: inherits
WARNING: loading non-allowed module: util
WARNING: loading non-allowed module: debug
WARNING: loading non-allowed module: depd
WARNING: loading non-allowed module: destroy
WARNING: loading non-allowed module: fs
WARNING: loading non-allowed module: stream
WARNING: loading non-allowed module: encodeurl
WARNING: loading non-allowed module: escape-html
WARNING: loading non-allowed module: etag
WARNING: loading non-allowed module: crypto
WARNING: loading non-allowed module: fs
WARNING: loading non-allowed module: events
WARNING: loading non-allowed module: fresh
WARNING: loading non-allowed module: fs
WARNING: loading non-allowed module: mime
WARNING: loading non-allowed module: path
WARNING: loading non-allowed module: fs
WARNING: loading non-allowed module: ./types.json
WARNING: loading non-allowed module: ms
WARNING: loading non-allowed module: on-finished
WARNING: loading non-allowed module: range-parser
WARNING: loading non-allowed module: path
WARNING: loading non-allowed module: statuses
WARNING: loading non-allowed module: stream
WARNING: loading non-allowed module: util
WARNING: loading non-allowed module: path
WARNING: loading non-allowed module: etag
WARNING: loading non-allowed module: proxy-addr
WARNING: loading non-allowed module: forwarded
WARNING: loading non-allowed module: ipaddr.js
WARNING: loading non-allowed module: qs
WARNING: loading non-allowed module: querystring
WARNING: loading non-allowed module: http
WARNING: loading non-allowed module: ./utils
WARNING: loading non-allowed module: ./utils
WARNING: loading non-allowed module: ./utils
WARNING: loading non-allowed module: depd
WARNING: loading non-allowed module: array-flatten
WARNING: loading non-allowed module: utils-merge
WARNING: loading non-allowed module: path
WARNING: loading non-allowed module: ./router/route
WARNING: loading non-allowed module: ./router
WARNING: loading non-allowed module: ./request
WARNING: loading non-allowed module: accepts
WARNING: loading non-allowed module: negotiator
WARNING: loading non-allowed module: mime-types
WARNING: loading non-allowed module: mime-db
WARNING: loading non-allowed module: ./db.json
WARNING: loading non-allowed module: path
WARNING: loading non-allowed module: depd
WARNING: loading non-allowed module: net
WARNING: loading non-allowed module: type-is
WARNING: loading non-allowed module: media-typer
WARNING: loading non-allowed module: mime-types
WARNING: loading non-allowed module: mime-db
WARNING: loading non-allowed module: ./db.json
WARNING: loading non-allowed module: path
WARNING: loading non-allowed module: http
WARNING: loading non-allowed module: fresh
WARNING: loading non-allowed module: range-parser
WARNING: loading non-allowed module: parseurl
WARNING: loading non-allowed module: proxy-addr
WARNING: loading non-allowed module: ./response
WARNING: loading non-allowed module: content-disposition
WARNING: loading non-allowed module: depd
WARNING: loading non-allowed module: encodeurl
WARNING: loading non-allowed module: escape-html
WARNING: loading non-allowed module: http
WARNING: loading non-allowed module: ./utils
WARNING: loading non-allowed module: on-finished
WARNING: loading non-allowed module: path
WARNING: loading non-allowed module: utils-merge
WARNING: loading non-allowed module: cookie-signature
WARNING: loading non-allowed module: crypto
WARNING: loading non-allowed module: ./utils
WARNING: loading non-allowed module: ./utils
WARNING: loading non-allowed module: ./utils
WARNING: loading non-allowed module: cookie
WARNING: loading non-allowed module: send
WARNING: loading non-allowed module: vary
WARNING: loading non-allowed module: ./middleware/query
WARNING: loading non-allowed module: serve-static
WARNING: loading non-allowed module: encodeurl
WARNING: loading non-allowed module: escape-html
WARNING: loading non-allowed module: parseurl
WARNING: loading non-allowed module: path
WARNING: loading non-allowed module: send
WARNING: loading non-allowed module: url

Unable to effectively deregisterMock

In a beforeEach block I am creating and registering a mock:

beforeEach ->
    knife = nodemock.mock()
    knife.counter = (counter += 1)
    console.log("made knife " + knife.counter)
    mockery.registerMock('../../knife', knife);

And unregistering it in afterEach:

afterEach ->
    mockery.deregisterMock('../../knife');

This mock is loaded by the code under test and executed. When the code under test executes a function on the mock, it prints the value of knife.counter so that I can see which instance it is invoking.

The problem I see is that even though beforeEach and afterEach is registering a new mock for each test, the code under test is invoking on the same instance (instance 1). Therefore the mock receives unexpected additional calls compared to the expectation and the test fails.

Help Defining Constructor in Mock Object

I'm having an issue mocking an object that's being instantiated using 'new'. I'm trying to Kinesis from AWS which is being constructed as follows:

var kinesis = new AWS.Kinesis({
    apiVersion: kinesisAPIName
});

I'm trying to create a mock object for kinesis:

var mock_aws = {config: {
            update: () => {}
        },
        Kinesis: {
            Kinesis: (params) => {},
            putRecord: (params, callback) => {
                if (params.PartitionKey === 'FAILED_PUT') {
                    callback('FAILED_PUT');
                } else {
                    callback(null, null);
                }
            }
        }
    };

When the Kinesis object is constructed I get a TypeError: AWS.Kinesis is not a constructor

Can't mock custom module

My Module:

// ./App/Services/MyBridge
import { NativeModules } from 'react-native'
export const MyBridge = NativeModules.MyBridge
export default MyBridge

My Mock:

// ./testSetup.js
mockery.enable()
mockery.registerAllowable('./App/Services/MyBridge', {
  nativeCall: () => {}
})

mockery.registerMock('./App/Services/MyBridge', {
  nativeCall: () => {}
})

Expected Behavior
MyBridge.nativeCall is mocked

Actual Behavior
Error message during test run Error: Cannot read property 'nativeCall' of undefined

I can't, for the life of me, figure this out. Mocking 3rd party modules works fine.
Any ideas? ([email protected])

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.