Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Testing TypeScript function which is not exported

I use Mocha/Chai for testing JavaScript front-end code and now we switched to TypeScript. I have several functions I want to test. But they shouldn't be exportable. Can I get an access to this functions and test it without adding export to them?

like image 355
michaeluskov Avatar asked Aug 10 '15 15:08

michaeluskov


People also ask

How do you test a function without exporting it?

Testing the non-exported function by testing the function(s) that use it is not really unit-testing. I agree that "private functions are an implementation detail" and it's not them that they need to be tested, but the behaviour of your publicly available function, class or whatever you have at hand.

How do I test a TypeScript function?

For TypeScript, unit tests are run against the generated JavaScript code. In most TypeScript scenarios, you can debug a unit test by setting a breakpoint in TypeScript code, right-clicking a test in Test Explorer, and choosing Debug.

How do you test if a function has been called in jest?

To check if a component's method is called, we can use the jest. spyOn method to check if it's called. We check if the onclick method is called if we get the p element and call it.

Do I need to export types TypeScript?

TypeScript uses the concept of modules, in the same way that JavaScript does. In order to be able to import a type from a different file, it has to be exported using a named or default export. The example above uses named exports and named imports.


1 Answers

While it is not possible to access non-exported function directly there is still a way to export them in a "semi-hidden" way. One possible approach would be:

// In your library module declare internal functions as non-exported like normal.
function someInternalFunctionA(x: number): number {
  return x;
}

function someInternalFunctionB(x: number): number {
  return x;
}

// At the bottom, offer a public escape hatch for accessing certain functions
// you would like to be available for testing.
export const _private = {
  someInternalFunctionA,
  someInternalFunctionB,
};

On test side you can do:

import { _private } from "./myModule";

test("someInternalFunctionA", () => {
  expect(_private.someInternalFunctionA(42)).toEqual(42);
});

What I like about the approach:

  • No need to mark someInternalFunctionA with export directly.
  • It should still be very obvious that the stuff under _private isn't officially part of the public interface.
like image 200
bluenote10 Avatar answered Sep 28 '22 09:09

bluenote10