1

I am new to Typescript and wanted to implement unit testing with Jest. I installed Jest, and when I run it I receive an error, I have simplified the code for this example, and it continues to fail:

FAIL  src\__tests__\validateSender.ts 
https validation
ReferenceError: validateSender is not defined

  at Object.<anonymous>.test (src/__tests__/validateSender.ts:10:10)
  at process._tickCallback (internal/process/next_tick.js:109:7)

The test which cannot find the function (./src/__tests__/validateSender.js):

import {} from "jest";
const connection = {
  encrypted: "undefined",
};
const req = {
  connection : ("{connection}"),
};

test("https validation", () => {
  expect(validateSender(req)).toThrow();
});

the function (./src/validateSender.js):

function validateSender(req) {
  if (typeof req.connection.encrypted === "undefined") {
    throw new CustomException("validateSender", "connection must be secured.");
  } else { return; }
}

my Jest package.json portion (./package.json):

"jest": {
    "transform": {
      "^.+\\.tsx?$": "<rootDir>/node_modules/ts-jest/preprocessor.js"
    },
    "testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$",
    "moduleFileExtensions": [
      "ts",
      "tsx",
      "js",
      "jsx",
      "json"
    ]
  }

I have attempted adding an import statement for the validateSender file directly, but it fails in the same way (on npm test from the root directory I added import {} from "./src/validateSender"; to the file and received the error above.)

It was also suggested I try import validateSender from "./src/validateSender"; but I receive error TS2307: Cannot find module './src/validateSender'.

It appears that I am missing some foundational knowledge for this process, but I have failed to find it in the TS handbook.

ConstantineK
  • 352
  • 4
  • 19

1 Answers1

1

In order to test a module member, it must be exported. Otherwise it isn't visible to your test.

This doesn't mean you need to export everything - you can test at your public API in most cases and cover the internal members.

Module File

export function validateSender(req) {
    if (typeof req.connection.encrypted === "undefined") {
        throw new Error("validateSender connection must be secured.");
    } else { return; }
}

Test File

import "jest";
import { validateSender } from './ext';

const connection = {
  encrypted: "undefined",
};
const req = {
  connection: ("{connection}"),
};

test("https validation", () => {
  expect(validateSender(req)).toThrow();
});

This will get you this far:

Test Result

And finally... to expect something to throw, you'll need to adjust your code to:

test("https validation", () => {
  expect(() => validateSender(req)).toThrow();
});

This passes an un-executed function that will be executed within the test, rather than executing the function and passing the result.

enter image description here

Fenton
  • 241,084
  • 71
  • 387
  • 401
  • Fenton, this is a great answer, and I think I may be asking the wrong question in the first place. I want to write a set of TS code and test it within itself, do I need to consider my code a module and export it or is there another approach that makes more sense? – ConstantineK Oct 22 '17 at 14:26
  • Also, when adding export before the function definition I now see TS2304 cannot find name validateSender in another .ts file I referenced via `validateSender(req);` which worked before export as preprended, is there something additional I should be doing? – ConstantineK Oct 22 '17 at 14:35
  • ok, looks like https://stackoverflow.com/questions/38158429/typescript-1-8-modules-import-all-files-from-folder clears up the rest, thanks again! – ConstantineK Oct 22 '17 at 15:16
  • @fenton... what do you mean by "...test at your public API in most cases and cover the internal members." Do you have a specific automation strategy in mind for this? We have many internal functions with very specific, detailed functionality... would be LOTS of end-to-end/wrapper code to get down to the specific place where that function is used. Seems like too much work for these types of functions. – JESii Feb 01 '22 at 18:35
  • @jesii the bit you quoted means you don't need to test each individual function, just the public part. This is the idea behind a more behavioural-driven approach. If you write tests to call each individually "tiny bit" it gets hard to change how you implemented all those tiny bits... which means the tests are tightly coupled to your implementation (not good) – Fenton Feb 03 '22 at 14:58