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

Explicitly setting modulePathIgnorePatterns to the default value breaks dontMock method #66

Closed
codyhatch opened this issue Jun 8, 2014 · 17 comments

Comments

@codyhatch
Copy link

Steps to repo:

  1. Create a new folder
  2. Run npm install jquery underscore jest-cli
  3. Run npm init and accept all defaults except setting the test command to jest
  4. Place this following test into __tests__
describe('SomeTest', function() {
    it("requires underscore (unmocked) and jQuery (mocked)", function() {
        jest.dontMock('underscore');
        var _ = require('underscore');
        var $ = require('jquery');

        expect(_.mock).toBeUndefined();
        expect($.mock).toBeDefined();
    })
});

If you run npm test it will pass, as you'd expect. Now edit the generated package.json to add "jest": {"modulePathIgnorePatterns": ["/node_modules/"]}, and rerun npm test. You'll get:

cody@possum jest-test $ npm test

> jest-test@0.0.0 test /Users/cody/Coding/jest-test
> jest

Found 1 matching tests...
 FAIL  __tests__/test.js (0.058s)
● SomeTest › it requires underscore (unmocked) and jQuery (mocked)
  - Expected undefined to be defined.
        at Spec.<anonymous> (/Users/cody/Coding/jest-test/__tests__/test.js:8:24)
        at Timer.listOnTimeout [as ontimeout] (timers.js:110:15)
1 tests failed, 0 tests passed (1 total)
Run time: 0.761s
npm ERR! Test failed.  See above for more details.
npm ERR! not ok code 0

In other words, setting modulePathIgnorePatterns to ["/node_modules/"] causes don'tMock() method to break mocking. This is true despite the fact that, according to the docs this is the default pattern.

I have confirmed this on the current version of jest on NPM, as well as the current HEAD commit (dbd9eb2). I have confirmed that setting modulePathIgnorePatterns to something like `["/nonsense_path/"] makes everything work.

In addition, note that the issue is that setting modulePathIgnorePatterns is causing calling dontMock() to break mocking. These tests both pass:

describe('SomeTest', function() {
    it("requires underscore (unmocked) and jQuery (mocked)", function() {
        jest.dontMock('underscore');
        var _ = require('underscore');
        var $ = require('jquery');

        expect(_.mock).toBeUndefined();
        expect($.mock).toBeUndefined();
    })
});

Showing that calling dontMock() causes all future requires to be unmocked. As well as:

describe('SomeTest', function() {
    it("requires underscore (unmocked) and jQuery (mocked)", function() {
        var _ = require('underscore');
        var $ = require('jquery');

        expect(_.mock).toBeDefined();
        expect($.mock).toBeDefined();
    })
});

Showing that without dontMock(), everything still works as expected. It's the combination of setting modulePathIgnorePatterns, calling dontMock(), and then trying to require something that should be mocked that's broken.

(I originally submitted the bug as #64, which I've closed because it turns out I was completely wrong about the actual issue.)

@codyhatch codyhatch changed the title Explicitly setting modulePathIgnorePatterns to the default breaks everything Explicitly setting modulePathIgnorePatterns to the default breaks dontMock method Jun 8, 2014
@codyhatch codyhatch changed the title Explicitly setting modulePathIgnorePatterns to the default breaks dontMock method Explicitly setting modulePathIgnorePatterns to the default value breaks dontMock method Jun 8, 2014
@madjam002
Copy link

I seem to be getting a problem similar to what you described with the following config:

  "jest": {
    "testDirectoryName": "test",
    "scriptPreprocessor": "test/.preprocessor.js",
    "testFileExtensions": [
      "coffee",
      "js"
    ],
    "moduleFileExtensions": [
      "coffee",
      "js"
    ]
  }

Calling jest.dontMock() seems to disable mocking on all require's, for example:

jest.dontMock '../src/service'

describe 'service', ->

  describe 'build', ->
    it 'should call the service builder', ->
      serviceBuilder = require '../src/service-builder'
      Service = require '../src/service'

serviceBuilder is my actual service builder instead of a mock, so I have to avoid using jest.dontMock and use require.requireActual instead.

I'm not sure whether these problems are related to your one, just thought I'd post about it here 😄

@lrowe
Copy link

lrowe commented Jun 21, 2014

I believe that the fix for #20 in 56c4f55 is incomplete as _getNormalizedModuleID will still return user:: for modules excluded from the resource map. While it does try to lookup the moduleResource:

    if (realAbsPath === null) {
      var moduleResource = this._getResource('JS', moduleName);
      if (moduleResource) {
        realAbsPath = moduleResource.path;
      }
    }

Here _getResource returns undefined. I believe this is because it only consults the Haste resourceMap, from which the file we're after has been explicitly excluded based on modulePathIgnorePatterns (which defaults to empty not "/node_modules/" as stated in the docs.)

Loader.prototype._getResource = function(resourceType, resourceName) {
  var resource = this._resourceMap.getResource(resourceType, resourceName);

  // TODO: Fix this properly in node-haste, not here :(
  if (resource === undefined && resourceType === 'JS' && /\//.test(resourceName)
      && !/\.js$/.test(resourceName)) {
    resource = this._resourceMap.getResource(
      resourceType,
      resourceName + '.js'
    );
  }

  return resource;
};

@messfromspace
Copy link

I have this issue with every module and not only with npm modules. So if I write something like this:

describe "Whatever", ->
  it "does something", ->
    jest.dontMock "../path/to/a"
    a = require "../path/to/a"
    b = require "../path/to/b"
    expect(a.mock).toBeUndefined()
    expect(b.mock).toBeDefined()

Test fails because b doesn't have mock property. So I need to use something like jest.mock "../path/to/b" or a = require.requireActual "../path/to/a" without dontMock to make it work as expected.

In my case dontMock is broken and disables mocks for every module.
Sorry for my bad English.

@aaronjensen
Copy link
Contributor

For me, simply setting unmockedModulePathPatterns to the react suggested one:

    "unmockedModulePathPatterns": [
      "<rootDir>/node_modules/react"
    ],

seems to break jest.dontMock completely as well, in that nothing else auto mocks after that one dontMock. This seems like a pretty severe issue, I'm surprised many other haven't been hitting it.

@aaronjensen
Copy link
Contributor

@messfromspace are you using coffeescript by chance for your other files? It seems like haste is not loading coffeescript files properly and therefore returning user:: as the module id for anything coffee... so when you dontmock one, it is the same as not mocking the others.

@pselden
Copy link

pselden commented Nov 25, 2014

Just would like to note that the original bug (Explicitly setting modulePathIgnorePatterns to the default value breaks dontMock method) is likely a documentation issue. The real default for this is just an empty array. Ignoring the actual node_modules folder will completely break mocking (because it needs to load into haste to mock it).

@jacobstr
Copy link

jacobstr commented Feb 4, 2015

@pselden In my experience, the bug interacts with testPathDirs as well.

testPathDirs

  A list of paths to directories that Jest should use to search for tests in.

  There are times where you only want Jest to search in a single 
  sub-directory (such as cases where you have a src/ directory in your repo),
  but not the rest of the repo.

^^ That sounds like it should only affect the discovery of test files.

It's an additionally painful ergonomics issue because the two settings look like ripe targets for improving Jest's poor startup time. And yes - excluding node_modules from testPathDirs does seem to make it run faster, but you've got this latent bug where the vaunted auto-mocking goes bonkers.

@gnesher
Copy link

gnesher commented Apr 16, 2015

Any intention on addressing this? been open for a while

davwards added a commit to davwards/cheshire-react that referenced this issue Apr 28, 2015
Looks like there's an open issue with Jest where due to the .haste-cache, certain configurations
and usages of dontMock() cause broken automocking behavior (jestjs/jest#66).
This bit me and I ended up having to wipe the .haste_cache completely. I'm opting not to use automocking
and just declare mocks explicitly; hopefully that will help.
@williamfligor
Copy link

I did some digging,

Setting modulePathIgnorePatterns causes Loader.prototype._getNormalizedModuleID in HasteModuleLoader.js to always return "user::" as the module id. This isn't a problem until you use dontMock and add an entry in HasteModuleLoader's this._explicitShouldMock. This entry looks like "user::": false.

When you require a module after using modulePathIgnorePatterns and using dontMock, the loader when it calls _shouldMock, always returns false because it calls _getNormalizedModuleID, which always returns "user::".

I think when using modulePathIgnorePatterns something goes wrong generating the resource map. Not sure though

Edit: Mocking started working again when I added "testFileExtensions": ["js", "jsx"], to my config

@ghost
Copy link

ghost commented Aug 4, 2015

Thank you for reporting this issue and appreciate your patience. We've notified the core team for an update on this issue. We're looking for a response within the next 30 days or the issue may be closed.

nheyn added a commit to nheyn/react-router-server that referenced this issue Aug 10, 2015
Get the RouteParser test working (had to move mock to test file because of jestjs/jest#66).
nheyn added a commit to nheyn/react-router-server that referenced this issue Aug 10, 2015
Add an express mock for routeToRouter tests (had to put mock to test file because of jestjs/jest#66).
@petejkim
Copy link

I am still experiencing this issue.

@Pharserror
Copy link

Not that I know of
On Sep 9, 2015 9:09 PM, "Peter Jihoon Kim" notifications@github.com wrote:

This is still a problem


Reply to this email directly or view it on GitHub
#66 (comment).

@AlcockP
Copy link

AlcockP commented Sep 15, 2015

I'm seeing the same issue if I specify a testPathDirs ... even if it is "testPathDirs": ["__tests__"]

After removing that from my config, everything works fine.

@mzratio
Copy link

mzratio commented Sep 20, 2015

I have the exact same problem described by @AlcockP. Removing testPathDirs resolved the problem and everything is mocked properly.

@CodeBaboon
Copy link

+1 on the problem with testPathDirs. Replacing dontMock() with require.requireActual('path') seems to be a viable workaround.

@cpojer
Copy link
Member

cpojer commented Mar 3, 2016

This should not be an issue any more with jest 0.7+.

@cpojer cpojer closed this as completed Mar 3, 2016
@github-actions
Copy link

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
Please note this issue tracker is not a help forum. We recommend using StackOverflow or our discord channel for questions.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 14, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests