title: Testing Imported Function with Parameter using Jest Mock Function / Jest spyOn
body: <p>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.</p>
  
  <p>So far I know that there are mainly three ways to test a function in Jest: </p>
  
  <p>1) <code>jest.fn()</code> </p>
  
  <p>2) <code>jest.spyOn</code></p>
  
  <p>3) <code>jest.mock('path')</code></p>
  
  <p>I have tried all three but none work.</p>
  
  <p>I wanted to test if the function returns a correct value(string) when called.
  I tried many different</p>
  
  <p>Here's my code: (I will show short snippets of my code in the later parts)</p>
  
  <p><strong>getDefApCode.ts</strong></p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-html lang-html prettyprint-override"><code>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'
  }</code></pre>
  </div>
  </div>
  </p>
  
  <p><strong>getDefAPCode.spec.ts</strong> >> Pattern 1 (using required + jest.fn)</p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-html lang-html prettyprint-override"><code>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", () =&gt; {
    beforeAll(async () =&gt; {
      await dbConnection(15, 3000);
    });
  
    afterAll(async () =&gt; {
      const conn = getConnection();
      await conn.close();
    });
  
    it("should get a default location code", async () =&gt; {
     const getLocation = require('../../../src/controllers/logic/getDefAPCode');
     const code = jest.fn(code =&gt; 'BKK');
     const getCode = getLocation(code);
     expect(getCode).toHaveBeenCalled();
  
     });
   });</code></pre>
  </div>
  </div>
  </p>
  
  <p>Error Message: </p>
  
  <pre><code>TypeError: getLocation is not a function
  </code></pre>
  
  <p><strong>getDefAPCode.spec.ts</strong> >> Pattern 2 (using spyON)</p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-html lang-html prettyprint-override"><code>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", () =&gt; {
    beforeAll(async () =&gt; {
      await dbConnection(15, 3000);
    });
  
    afterAll(async () =&gt; {
      const conn = getConnection();
      await conn.close();
    });
  
    const { getDefaultLocationCode, getDefaultDepartureCode, getDefaultDestinationCode } = require('../../../src/controllers/logic/getDefaultLocationCode');
    
    it("should get a default location code", async () =&gt; {
     const spy = jest.spyOn(getDefaultLocationCode, 'getDefaultLocationCode');
     getDefaultLocationCode.getDefaultLocationCode('AKJ');
     expect(spy).toHaveBeenCalled();
    });
   });</code></pre>
  </div>
  </div>
  </p>
  
  <p>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)</p>
  
  <p>Error Message: </p>
  
  <pre><code>Cannot spy the getDefaultLocationCode property because it is not a function; undefined given instead
  </code></pre>
  
  <blockquote>
    <p>31 |      const spy = jest.spyOn(getDefaultLocationCode, 'getDefaultLocationCode');</p>
  </blockquote>
  
  <p>Past Error Messages</p>
  
  <pre><code>error TS2349: This expression is not callable.
        Type 'typeof import("/app/src/controllers/logic/getDefAPCode")' has no call signatures.
  </code></pre>
  
  <p>another one</p>
  
  <pre><code>expect(received).toHaveBeenCalled()
  
  Matcher error: received value must be a mock or spy function
  
  Received has type:  string
  Received has value: "NRT"
  </code></pre>