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

TypeError: _get__(...).__REWIRE__ is not a function #109

Open
codejet opened this Issue Mar 15, 2016 · 48 comments

Comments

Projects
None yet
@codejet
Copy link

codejet commented Mar 15, 2016

No matter what I try with exports and imports, I always get:

TypeError: _get__(...).__REWIRE__ is not a function

I added the plugin to our .babelrc for the tests and babel-plugin-rewire.js definitely gets executed.

I couldn't find any really similar issue. Am I missing something obvious?

@speedskater

This comment has been minimized.

Copy link
Owner

speedskater commented Mar 15, 2016

@codejet is it possible that you have a type in your code and use REWIRE instead of Rewire (https://github.com/speedskater/babel-plugin-rewire).
I would even recommend to use the set method.
Does this solution help you?

@codejet

This comment has been minimized.

Copy link

codejet commented Mar 15, 2016

thanks @speedskater, but it doesn't seem to matter whether REWIRE or Rewire...

TypeError: _get__(...).__Rewire__ is not a function

@robin-barnes-triptease

This comment has been minimized.

Copy link

robin-barnes-triptease commented Mar 15, 2016

I also have what appears to be the same problem:

undefined is not a constructor (evaluating '_get__('consoleLogger').__Rewire__('getWindow', function () {
          return windowMock;
        })')

undefined is not a constructor seems to happen when using either phantom or mocha, not sure which, but basically it's complaining because

moduleName.__Rewire__

is not a function. Note this was working fine until I reinstalled my npm modules, then it broke.

@speedskater

This comment has been minimized.

Copy link
Owner

speedskater commented Mar 16, 2016

@codejet , @robin-barnes-triptease thank you. Could one of you please create a PR with a minimum sample, similar to the ones existing in the repo?

@mmahalwy

This comment has been minimized.

Copy link

mmahalwy commented Mar 16, 2016

@codejet I am experiencing the same problem with PhantomJS but not in Chrome with karma running my tests. Did you get around fixing this? CC: @robin-barnes-triptease

@codejet

This comment has been minimized.

Copy link

codejet commented Mar 17, 2016

@mmahalwy no, unfortunately i didn't. we are using mocha here.

@uriklar

This comment has been minimized.

Copy link

uriklar commented Mar 23, 2016

+1

@codejet

This comment has been minimized.

Copy link

codejet commented Mar 23, 2016

a colleague of mine investigated, and according to him babel-register prevents rewiring of modules living inside node_modules in our case.

@jonashartwig

This comment has been minimized.

Copy link

jonashartwig commented Mar 23, 2016

Same issue here using babel 6, mocha, karma on chrome with rc1:

import * as ConfigService from "../src/services/configService";

const getEnvironmentConfigurationMock = () => Promise.resolve({});

ConfigService.__Rewire__("getEnvironmentConfiguration", getEnvironmentConfigurationMock);

where configService:

var environmentConfig = undefined;

export function getEnvironmentConfiguration () {
        ... return some form of promise
    });
}
@ModuloM

This comment has been minimized.

Copy link

ModuloM commented Mar 24, 2016

I had the same problem, but manage to fix it.

In your case @jonashartwig, it will be something like, switching:
import * as ConfigService from (...)
To:
import { getEnvironmentConfiguration, __RewireAPI__ as configServiceRewireApi } from (...)

And finally in the code
configServiceRewireApi.__Rewire__("getEnvironmentConfiguration", (...)

Hope it helps.

@spncrlkt

This comment has been minimized.

Copy link
Contributor

spncrlkt commented Mar 24, 2016

Ran into this today:

import * as things from './myThings.js';
...
things.__Rewire__(...)

Throws:
TypeError: _get__('things').__REWIRE__ is not a function

I wanted to keep the import * as syntax, so I found a workaround by importing the things and the API separately:

import * as things from 'myThings.js';
import { __RewireAPI__ as ThingsRewireAPI } from 'myThings.js';
...
ThingsRewireAPI.__Rewire__(...)
@joshnuss

This comment has been minimized.

Copy link

joshnuss commented Mar 28, 2016

It seems you can't rewire a dependency that is not used. This caused the issue for me.

It's a little confusing when doing TDD, cause you might want to rewire a service before anything actually uses it.

// notice Foo is never used, so babel doesnt bother loading it
import Foo from "./foo"
export default class Bar {
}
import Bar from "./bar"

Bar.__Rewire__('Foo', 1); // TypeError: _get__(...).__Rewire__ is not a function

This can be fixed by adding a reference to the import anywhere in your code

import Foo from "./foo"

Foo; // now the module will be included

export default class Bar {
}
@speedskater

This comment has been minimized.

Copy link
Owner

speedskater commented Mar 28, 2016

@spncrlkt, @ModuloM, @robin-barnes-triptease , @jonashartwig The behaviour regarding wildcard imports is intentional. The reason is that if we would add the rewire api to the wildcard import it could break the contract of modules expecting certain exports.

@joshnuss You are right, rewiring a dependency which is not used or does not exist causes an error at the moment. I think we should be able to ignore such cases, as rewiring not existing dependencies won't change anything. @TheSavior what do you think?
Anyway @joshnuss could you please create a PR for a failing usage test?

@mmahalwy

This comment has been minimized.

Copy link

mmahalwy commented Apr 13, 2016

I am still getting this error with as simple as:

import React, { Component, PropTypes } from 'react';
import { connect } from 'react-redux';
import { asyncConnect } from 'redux-async-connect';

import Grid from 'react-bootstrap/lib/Grid';
import Row from 'react-bootstrap/lib/Row';
import Col from 'react-bootstrap/lib/Col';

import { load } from 'redux/modules/image_attributions';

@asyncConnect([{
  promise({ store: { dispatch } }) {
    return dispatch(load());
  }
}])
@connect(
  state => ({
    imageAttributions: state.imageAttributions.entities
  })
)
export default class ImageAttribution extends Component {
  static propTypes = {
    imageAttributions: PropTypes.array
  };

  render() {
    return (
      <Grid style={{marginTop: '140px'}}>
      </Grid>
    );
  }
}

and test:

import ImageAttributions from './index';

console.log(ImageAttributions); // function Connect(props, context) { ... }
console.log(ImageAttributions.__GetDependency__); // undefined
console.log(ImageAttributions.__Rewire__); // undefined

This only happens with phantomjs and only when I have export default and using babel 6:

{
  "presets": ["react", "es2015", "stage-0"],
  "plugins": [
    "transform-runtime",
    "add-module-exports",
    "transform-decorators-legacy",
    "transform-react-display-name"
  ],
  "env": {
    "test": {
      "plugins": [
        "rewire"
      ]
    },

My work around has been:

import ImageAttributions, { __RewireAPI__ as ImageAttributionsApi } from './index';

which is weird since export default should already have the apis.

@speedskater

This comment has been minimized.

Copy link
Owner

speedskater commented Apr 26, 2016

@mmahalwy maybe this could be related to the decorators in your sample. What happens if your separate the declaration of the component and the export?

@mmahalwy

This comment has been minimized.

Copy link

mmahalwy commented Apr 28, 2016

i can give it a try and report back

@mmahalwy

This comment has been minimized.

Copy link

mmahalwy commented May 19, 2016

@speedskater getting same problem with non decoratored file

@asgarddesigns

This comment has been minimized.

Copy link

asgarddesigns commented Jun 23, 2016

I found declaring an anonymous function as default export directly caused this error, whereas assigning to a const and exporting that worked.

e.g.
doesn't work:

default export ({ path, func }) => {
    function request(params) {
    //do stuff
    }
    return { request };
};

does work

const method = ({ path, func }) => {
  function request(params) {
    //do stuff
  }
  return { request };
};
export default method;
@speedskater

This comment has been minimized.

Copy link
Owner

speedskater commented Jul 5, 2016

@asgarddesigns thanks for figuring this out. Could you please create a PR with a failing sample with your example?

@BenoitAverty

This comment has been minimized.

Copy link

BenoitAverty commented Jul 7, 2016

I found the same thing as @asgarddesigns. However, it is still related to the import not being used because adding a reference to the unused import fixed the problem.

@asgarddesigns

This comment has been minimized.

Copy link

asgarddesigns commented Jul 10, 2016

@speedskater sorry, been on holidays. Will try and push something up when I get a chance (an remember what I was actually doing!).

@liamfd

This comment has been minimized.

Copy link

liamfd commented Jul 13, 2016

I encountered an issue that may be related (version 1.0.0-rc-3, using it with webpack).

I have two modules, both of which consist of a number of exported functions. However, when I imported them, __Rewire_API__ worked fine for one, but not the other.

When trying to track down the difference between my modules, I discovered that while __Rewire_API__ is defined when importing this module:

const foo = 'TEST';
export const bar = () => {
  return foo;
};

It is undefined (both as a default import and as a named import) while importing this one:

export const bar = () => {
  return 'TEST (not Foo!)';
};

This also does not work (notice that foo is defined, but unused):

const foo = 'bar';
export const bar = () => {
  return 'TEST (not Foo!)';
};

Here is the module that I imported the three of these with:

import { bar, __RewireAPI__ as RewireBar } from './bar';
console.log('bar:', bar());
console.log('rewire:', RewireBar);

So it seems that you need at least one top level variable that is used within the module for __RewireAPI__ to work when that module is imported.

I suppose that makes sense, as there would be nothing for rewire to, well, rewire, but it occurred during development and I couldn't figure out for the life of me what was happening, so if it would be possible to have a descriptive error, or simply have __Rewire_API__ work anyways, that would be great.

Let me know if this is the right place for this or if I can provide any more detail.

@TheSavior

This comment has been minimized.

Copy link
Contributor

TheSavior commented Jul 13, 2016

@liamfd Do you still have this problem with the latest version (1.0.0-rc-4)

@liamfd

This comment has been minimized.

Copy link

liamfd commented Jul 13, 2016

@TheSavior unfortunately yes, the issue still seems to be present with 1.0.0-rc-4.

@panzerdp

This comment has been minimized.

Copy link

panzerdp commented Aug 7, 2016

The problem is still present in 1.0.0-rc-5.
I included rewire as a plugin in .babelrc. Then tried mocha tests without modifications and it fails: TypeError: _get__(...) is not a function . Tests were working fine before, without rewire plugin.
I am using mocha 2.5.3 with babel.

selection_004

@tchock

This comment has been minimized.

Copy link

tchock commented Oct 3, 2016

I still got this error in 1.0 doing something like this:

PushQueue.js

export default class PushQueue {
  // ...
}

PushQueue.spec.js

const MockQueueItem = function MockQueueItem(action, payload) {
  console.log('should be called', action, payload);
  return { action, payload };
};

import PushQueue from './PushQueue';

describe('PushQueue', function () {
  beforeEach(function () {
    PushQueue.__Rewire__('PushQueueItem', MockQueueItem);
    this.queue = new PushQueue();
  });

  afterEach(function () {   
    PushQueue.__ResetDependency__('PushQueueItem');
  });

  // tests are here ...
});

As @mmahalwy said: __Rewire__ and __ResetDependency__ are undefined.

When I also import the __RewireAPI__ from the PushQueue.js file I can call these functions there but it doesn't change the import when calling a function that uses the PushQueueItem.

Is there some update about this issue?

@speedskater

This comment has been minimized.

Copy link
Owner

speedskater commented Oct 10, 2016

@tchock thanks for providing the sample. Could you please provide the complete code of PushQueue so that i can try to tackle the issue asap?

@speedskater

This comment has been minimized.

Copy link
Owner

speedskater commented Nov 9, 2016

@tchock Thanks for providing the complete code and sorry for my delay but I have been on holidays over the last 3 weeks. I will have a look at the code tomorrow in the evening and let you know whether I can figure something out.

@speedskater

This comment has been minimized.

Copy link
Owner

speedskater commented Nov 10, 2016

@tchock I have not found your problem till now (trying to create a sample project but i think i will have to do it over the weekend). But maybe your issue is related to issue #93 and the proposed fix in the sample project danawoodman/webpack-babel-rewire-bug-example#1

@jonashartwig

This comment has been minimized.

Copy link

jonashartwig commented Nov 11, 2016

I usually do it like this:

import PushQueue from './PushQueue';
import { __RewireAPI__ } from "./PushQueue";

this usually works for me

@renaudtertrais

This comment has been minimized.

Copy link

renaudtertrais commented Nov 16, 2016

I got this issue also but that was because my isparta config in webpack of karma was incorrect.
I fixed it with (it's in the README btw):

webpack: {
  isparta: {
    embedSource: true,
    noAutoWrap: true,
    babel: {
      plugins: 'rewire'
    }
  },

  module: {
    preLoaders: [
      {
        test: /\.jsx?$/,
        loader: 'isparta',
        include: path.join(__dirname, 'src'),
        exclude: /node_modules/,
      }
    ]
  }
}
@tchock

This comment has been minimized.

Copy link

tchock commented Nov 17, 2016

The import { __RewireAPI__ } from "./PushQueue"; code also doesn't really work (tried this already some time ago). I've already have the right isparta config for this. Hopefully this will be fixed with the issue @speedskater mentioned. I will hold my hopes high :)

@tchock

This comment has been minimized.

Copy link

tchock commented Nov 20, 2016

Ok I got it to work! I had the plugin added to isparta and also to the babel-loader.
This caused that Rewire was undefined.

I removed the plugin from the babel-loader and it worked.

@speedskater maybe this should be added to the readme?

@speedskater

This comment has been minimized.

Copy link
Owner

speedskater commented Nov 21, 2016

@tchock Thanks for your feedback. I added it to the readme. Furthermore I created a working unit test with your sample and added it to the repository.
Is there any reason why you are using isparta instead of babel-plugin-istanbul ?

@tchock

This comment has been minimized.

Copy link

tchock commented Nov 21, 2016

@speedskater cool! I was just not aware of the babel-plugin-istanbul. Is this in any way better or better maintained? Because isparta doesn't see that much love recently.

@speedskater

This comment has been minimized.

Copy link
Owner

speedskater commented Nov 21, 2016

@tchock. Don't know which one is better maintained, but the last times i have tried babel-plugin-istanbul it worked almost out of the box while maintaining line numbers.

@mayeaux

This comment has been minimized.

Copy link

mayeaux commented Dec 21, 2016

@joshnuss Thanks, for the life of me I could not figure that out.

@Claire

This comment has been minimized.

Copy link

Claire commented Jan 6, 2017

+1

I don't thave the webpack, .babelrc config conflict.

Can't use __Rewire__ method with test running in Phantomjs which our Jenkins CI build uses. Any ETA?

@leff leff referenced this issue Jan 6, 2017

Closed

WebRTC tests are hard #1

@sculove

This comment has been minimized.

Copy link

sculove commented Jan 13, 2017

+1

@noahehall

This comment has been minimized.

Copy link

noahehall commented May 24, 2017

just wrestled with this for an hour, if you're component exports a default && named export, make sure your default export is the one you're testing

@csvan

This comment has been minimized.

Copy link

csvan commented Jun 1, 2017

@ModuloM solution worked in my case. I'm using Karma with the webpack plugin, and tests are passing both in Chrome and PhantomJS.

@JakubPetriska

This comment has been minimized.

Copy link

JakubPetriska commented Jun 5, 2017

I also have similar issues and I'm able to fix it with solution from @ModuloM .

+1

@pavelkukov

This comment has been minimized.

Copy link

pavelkukov commented Jun 18, 2017

__Rewire__ method is exported as a member of default.
It is possible to use it with import all:

import * as MyModule from 'path'
MyModule.default.__Rewire__('do', magic)

default will be exported from your module.
For example, export { a, b, c } will have unexpected default when imported.

import * as MyModule from 'path'
Object.keys(MyModule) // [a, b, c, default]
@Lian-LF

This comment has been minimized.

Copy link

Lian-LF commented Oct 27, 2017

In my case, it seems like the babel is not set properly. I moved the babel setting from package.json to .babelrc, use "babel" as "inherit" and require "babel-register" then it worked.

@laddi

This comment has been minimized.

Copy link

laddi commented Feb 8, 2018

We've been scratching our heads on this for a couple of days now. We ran into all the same problems when trying to rewire in files that only contained exported functions. What we ran into was that __RewireAPI__ was always undefined and would only become defined when we added a local variable or function.

But we tried adding a export default { method1, method2, ... } and that seemed to clear it up for us. So it's obvious that if no default export exists (and no local variables/functions) then __RewireAPI__ will never be added to the file. But this workaround works fine for us, just a shame it took us this long to discover it... 😛

Babel settings are still in package.json for us so that clearly wasn't a factor. I'm not sure if this is a bug or not but the solution wasn't obvious and this kind of contradicts the documentation. Unless we are seriously misunderstanding that... 😉

@zorobabel

This comment has been minimized.

Copy link

zorobabel commented Oct 10, 2018

It's 2018 and @asgarddesigns's solution works!

@nnennaude

This comment has been minimized.

Copy link

nnennaude commented Dec 24, 2018

Just FYI, for me this problem appeared when I added non-default exports to module I was testing.

For example, when it was just

// MyModule.js
export default ObjectA;
// MyModule.spec.js
import ObjectA from './MyModule'

ObjectA.__Rewire('myImport', 5);

it worked just fine.

But when I changed it to

// MyModule.js
export { objectA as default, objectB };

then I got the error.

When I changed it back, the problem went away. I ended up deciding to revert to the original code, and find another way to design my code such that I would not have to export objectB.
hjh
kjl

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment