Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Rewire with TypeScript

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.

like image 930
oar.garuna Avatar asked Oct 11 '16 12:10

oar.garuna


1 Answers

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.
like image 52
Tim Perry Avatar answered Sep 29 '22 01:09

Tim Perry