0
votes

I'm trying to write a unit test for a Node.js project's logic using Jest. However, most documentations only provide a case for importing a module or class, however, in my case, my module only contains functions.

So far I know that there are mainly three ways to test a function in Jest:

1) jest.fn()

2) jest.spyOn

3) jest.mock('path')

I have tried all three but none work.

I wanted to test if the function returns a correct value(string) when called. I tried many different

Here's my code: (I will show short snippets of my code in the later parts)

getDefApCode.ts

export function getDefApCode(code: string) {
  switch (code) {
    case 'BKK':
      return 'NRT'
    case 'CTX':
      return 'ICN'
    case 'SIN':
      return 'TPE'
    default:
      return code
  }
}

export function getDefaultDepartureCode(code: string) {
  return code ? getDefaultLocationCode(code) : 'LHR'
}

export function getDefaultDestinationCode(code: string) {
  return code ? getDefaultLocationCode(code) : 'ZRH'
}

getDefAPCode.spec.ts >> Pattern 1 (using required + jest.fn)

import { Connection, getConnection, getConnectionOptions } from "typeorm";
import { bootstrap, dbConnection } from "../../../src/app";
import { TourSearchParamsFactory } from "../../helpers/typeOrmFactory";
import * as getDefAPCode from "../../../src/controllers/logic/getDefAPCode";

describe("Logic Test", () => {
  beforeAll(async () => {
    await dbConnection(15, 3000);
  });

  afterAll(async () => {
    const conn = getConnection();
    await conn.close();
  });

  it("should get a default location code", async () => {
  	const getLocation = require('../../../src/controllers/logic/getDefAPCode');
  	const code = jest.fn(code => 'BKK');
  	const getCode = getLocation(code);
  	expect(getCode).toHaveBeenCalled();

   });
 });

Error Message:

TypeError: getLocation is not a function

getDefAPCode.spec.ts >> Pattern 2 (using spyON)

import { Connection, getConnection, getConnectionOptions } from "typeorm";
import { bootstrap, dbConnection } from "../../../src/app";
import { TourSearchParamsFactory } from "../../helpers/typeOrmFactory";
import * as getDefaultLocationCode from "../../../src/controllers/logic/getDefaultLocationCode";


describe("Logic Test", () => {
  beforeAll(async () => {
    await dbConnection(15, 3000);
  });

  afterAll(async () => {
    const conn = getConnection();
    await conn.close();
  });

  const { getDefaultLocationCode, getDefaultDepartureCode, getDefaultDestinationCode } = require('../../../src/controllers/logic/getDefaultLocationCode');
  
  it("should get a default location code", async () => {
  	const spy = jest.spyOn(getDefaultLocationCode, 'getDefaultLocationCode');
  	getDefaultLocationCode.getDefaultLocationCode('AKJ');
  	expect(spy).toHaveBeenCalled();
  });
 });

These are some error messages appear when I tried a different pattern (I didn't keep track of all of the test code pattern, will add the test code pattern once I fixed docker)

Error Message:

Cannot spy the getDefaultLocationCode property because it is not a function; undefined given instead

31 | const spy = jest.spyOn(getDefaultLocationCode, 'getDefaultLocationCode');

Past Error Messages

error TS2349: This expression is not callable.
      Type 'typeof import("/app/src/controllers/logic/getDefAPCode")' has no call signatures.

another one

expect(received).toHaveBeenCalled()

Matcher error: received value must be a mock or spy function

Received has type:  string
Received has value: "NRT"
1
Where are you defining getLocation?izambl
@izambl getLocation >> I defined it inside 'it'lane3445

1 Answers

0
votes

I figured out that I don't have to use mock function in this case.

I stored argument in a variable and then I use the variable instead using a string directly.

Here's how I edit my test code

  it("should get a default location code", () => {
    const code = 'BKK';
    expect(code).toHaveBeenCalled();
   });