15

I am working on a React-Native project using TypeScript. To write my unit tests I would like to use the babel-plugin-rewire to mock my module imports. However, TypeScript adds a _1 suffix at the end of imports while converting from ES6 to ES5, and this breaks my test code.

Consider the following:

import Test from 'test-file';

this might be converted by TypeScript to:

var test_file_1 = require('test-file');

To mock the Test class using the Rewire plugin I would have to write:

ComponentToTest.__Rewire__('Test', TestMock);

but since the import has been renamed this will break.

Though this is by design, I would love to know if there are any workarounds.

Thanks.

oar.garuna
  • 472
  • 1
  • 3
  • 13
  • 2
    How did you manage to import tested module into the spec file (ie. `import { SomeClass, __Rewire__ } from '../src/SomeClass';`)? When I try to run the test, the compiler prints the following error `"SomeClass" has no exported member '__Rewire__'`. P.S. spec files are also written in TypeScript. – knee-cola Nov 20 '17 at 16:50

1 Answers1

14

I don't know about Babel-Plugin-Rewire but if you use TypeScript with Rewire alone, including compiling ES6 modules to ES5, you can easily mock the generated file import directly.

I.e. This should work:

ComponentToTest.__set__('test_file_1', { default: TestMock });

That does then depends on the _1 suffix, which could plausibly change in later TypeScript releases or if you make certain changes to the TypeScript code itself. I think that's fairly low risk though.

Full Rewire + TS example:

Component.ts:

import DefaultComponent from "other-component";
import { IndividuallyExportedComponent } from "yet-another-component";

// ... Do something worth testing

Component-Test.ts:

import rewire = require("rewire");
let RewiredComponent = rewire("../src/Component");

let defaultComponentMock = { /* Make a mock of your dependency */ };
RewiredComponent.__set__('other_component_1', {
    default: defaultComponentMock
});

let individuallyExportedMock = { /* Make a mock of your dependency */ };
RewiredComponent.__set__('yet_another_component_1', {
    IndividuallyExportedComponent: individuallyExportedMock
});

// RewiredComponent has the wrong type now. YMMV, but I'm doing type-wrangling
// that looks something like:

import * as RealComponent from "../src/Component";
let Component: typeof RealComponent & typeof RewiredComponent = <any> RewiredComponent;

// 'Component' now has the same type as the real module, plus the
// .__set__ etc methods from Rewire.
Philipp Kief
  • 8,172
  • 5
  • 33
  • 43
Tim Perry
  • 11,766
  • 1
  • 57
  • 85