theKashey / rewiremock

The right way to mock dependencies in Node.js or webpack environment.
MIT License
490 stars 31 forks source link

difficulty using rewiremock.proxy with local file #76

Open loicpw opened 5 years ago

loicpw commented 5 years ago

Hi guys,

I'm having troubles trying to inject dependencies into a tested module within create-react-app environment.

my test configuration looks like this:

beforeEach(() => {
        [...]

        // this works well:
        StaggeredMotion = rewiremock.proxy('react-motion/lib/StaggeredMotion', {
            raf: mockRaf.raf,
            'performance-now': mockRaf.now,
        });

        // this fails: see error below
        MyComponent = rewiremock.proxy('../mycomponent', {
            'react-motion': {
                StaggeredMotion: StaggeredMotion,
            },
        }).default;
});

Here's the error I get:

/[...]/mycomponent.js:13
    import './mycompoent.css';
           ^^^^^^^^^^^^^^^^^^^^^^

    SyntaxError: Unexpected string

      at Function.mockLoader [as _load] (node_modules/rewiremock/lib/executor.js:325:37)
      at requireModule (node_modules/rewiremock/lib/executor.js:75:47)

actually every import statement will fail with "Unexpected string" or "Unexpected token" at this point.

If I use:

        // this has no effect
        MyComponent = rewiremock.proxy(() => require('../mycomponent'), {
            'react-motion': {
                StaggeredMotion: StaggeredMotion,
            },
        }).default;

This does not fail but it has simply no effect (nothing is changed). As a workaround I manually inject my mock 'StaggeredMotion' as I have control over the code of 'mycomponent' but this is not ideal. am I missing something ? Thanks !

theKashey commented 5 years ago

So - you just have an issue with importing ESModules from node_modules, that’s absolutely ok-ish. By default, even if you are running your tests with Babel/register, it will ignore node_modules. So, as long as Babel won’t transpile code, and node won’t understand imports - it does not work.

How to solve:

loicpw commented 5 years ago

thanks, sorry I'm not sure to understand as I'm quite new to Javascript and React, I tried the following in my test script but this didn't work:

require('babel-register');
const { esm_modules } = require('require-control');
esm_modules();
theKashey commented 5 years ago

Sorry, I've read your issue a bit inaccurate - the original problem import './mycompoent.css'; is happening in your own mycomponent.js.

That means that babel-register is not working as expected. Probably you have modules:false setting in your .babelrc - could you please check it?

loicpw commented 5 years ago
./node_modules/babel-plugin-dynamic-import-node/.babelrc:
-------------------------------------------------
{
  "presets": [
    "airbnb"
  ],
  "plugins": [
    "add-module-exports",
    ["transform-replace-object-assign", { "moduleSpecifier": "object.assign" }],
  ],
}

./node_modules/compare-module-exports/.babelrc:
-------------------------------------------------
{
  "presets": [],
  "env": {
    "cjs": {
      "presets": [
        [
          "env",
          {
            "targets": {
              "node": "7.0",
              "ie": 11
            }
          }
        ]
      ]
    }
  }
}

./node_modules/eslint-plugin-jsx-a11y/.babelrc:
-------------------------------------------------
{
  "presets": ["es2015"],
  "plugins": [
    "transform-object-rest-spread",
    "transform-flow-strip-types",
  ]
}

./node_modules/esrecurse/.babelrc:
-------------------------------------------------
{
    "presets": ["es2015"]
}

./node_modules/estraverse/.babelrc:
-------------------------------------------------
{
    "presets": ["es2015"]
}

./node_modules/fileset/.babelrc:
-------------------------------------------------
{
  "presets": ["es2015"],

  "plugins": [
    "add-module-exports"
  ]
}

./node_modules/identity-obj-proxy/.babelrc:
-------------------------------------------------
{
  "presets": [ "es2015", "stage-0" ],
}

./node_modules/jsx-ast-utils/.babelrc:
-------------------------------------------------
{
  "presets": ["es2015"]
}

./node_modules/optimize-css-assets-webpack-plugin/.babelrc:
-------------------------------------------------
{
  "presets": [
    [
      "env",
      {
        "useBuiltIns": true,
        "targets": {
          "node": "current"
        },
        "exclude": [
          "transform-async-to-generator",
          "transform-regenerator"
        ]
      }
    ]
  ],
  "plugins": [
    [
      "transform-object-rest-spread",
      {
        "useBuiltIns": true
      }
    ]
  ]
}

./node_modules/wipe-node-cache/.babelrc:
-------------------------------------------------
{
  "presets": [],
  "env": {
    "cjs": {
      "presets": [
        [
          "env",
          {
            "targets": {
              "node": "7.0",
              "ie": 11
            }
          }
        ]
      ]
    }
  }
}

./node_modules/wipe-webpack-cache/.babelrc:
-------------------------------------------------
{
  "presets": [],
  "env": {
    "cjs": {
      "presets": [
        [
          "env",
          {
            "targets": {
              "node": "7.0",
              "ie": 11
            }
          }
        ]
      ]
    }
  }
}

Also note I'm using create-react-app, I didn't change any config so far but I have no clue if they're doing something special... Thanks !

theKashey commented 5 years ago

ok, not it's clear why it's not working - there is no setup for a babel. If you are using CRA and running npm run test, then according to the documentation you should have Jest. Jest should handle babel out of the box, and also should handle mocking (via jest.mock). ! rewrimock is incompatible with Jest

In the same time - as long as you were able to mock something, and have babel related issues - it's not the default CRA config.

Then - just drop .babelrc to your tests or root dirrectory

{ 
 presets: ["env","react"]
}
loicpw commented 5 years ago

Thanks for your help, sorry I need to use react-app-rewired to be able to customize babelrc, I don't have time right now I'm gonna try this a little bit later asap...