question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Jest spyOn() calls the actual function instead of the mocked

See original GitHub issue

I’m testing apiMiddleware that calls its helper function callApi. To prevent the call to actual callApi which will issue the api call, I mocked the function. However, it still gets called.

apiMiddleware.js

import axios from 'axios';

export const CALL_API = 'Call API';

export const callApi = (...arg) => {
  return axios(...arg)
  	.then( /*handle success*/ )
  	.catch( /*handle error*/ );
};

export default store => next => action => {
  // determine whether to execute this middleware
  const callAPI = action[CALL_API];
  if (typeof callAPI === 'undefined') {
    return next(action)
  }

  return callAPI(...callAPI)
  	.then( /*handle success*/ )
  	.catch( /*handle error*/ );
}

apiMiddleware.spec.js

import * as apiMiddleware from './apiMiddleware';

const { CALL_API, default: middleware, callApi } = apiMiddleware;

describe('Api Middleware', () => {

  const store = {getState: jest.fn()};
  const next = jest.fn();
  let action;

  beforeEach(() => {
    // clear the result of the previous calls
    next.mockClear();
    // action that trigger apiMiddleware
    action = {
      [CALL_API]: {
        // list of properties that change from test to test 
      }
    };
  });

  it('calls mocked version of `callApi', () => {
	const callApi = jest.spyOn(apiMiddleware, 'callApi').mockReturnValue(Promise.resolve());

	// error point: middleware() calls the actual `callApi()` 
	middleware(store)(next)(action);

	// assertion
  });
});

Please ignore the action’s properties and argument of callApi function. I don’t think they are the concern of the point I’m trying to make.

Tell me if you need further elaboration.

stackoverflow

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Reactions:2
  • Comments:27 (9 by maintainers)

github_iconTop GitHub Comments

73reactions
rickhanloniicommented, Nov 27, 2018

@NERDYLIZARD sorry for the delay here!

By default jest.spyOn() does not override the implementation (this is the opposite of jasmine.spyOn). If you don’t want it to call through you have to mock the implementation:

const callApi = jest.spyOn(apiMiddleware, 'callApi').mockImplementation(() => Promise.resolve());
34reactions
JonathanHolveycommented, Apr 12, 2019

I seem to be having this problem as well, but the solution that @rickhanlonii proposed isn’t working for me. I’m following the documentation for jest.spyOn(), but the mocked function is still being called when running the tests.

processing.js

const saveVisit = (visit) => {
  return database.put(visit)
}

const processVisit = (visit) => {
  if (visit.status.includes('PROCESSED') {
    saveVisit(visit)
    return promise.resolve()
  }

  saveVisit({ ...visit, status: ['PROCESSED'] })
  return visit.status
}

processing.test.js

const subject = require('../processing')

test('processVisit for processed visit returns null', () => {
  const visit = { status: ['PROCESSED'] }

  jest.spyOn(subject, 'saveVisit').mockImplementation(() => Promise.resolve())
  return subject.processVisit(visit).then(result => expect(result).toBeNull())
})
Read more comments on GitHub >

github_iconTop Results From Across the Web

Jest spyOn() calls the actual function instead of the mocked
The jest mocking only works on imported functions. In your apiMiddleware.js the default function is calling callApi variable, ...
Read more >
How to Mock Using Jest.spyOn (Part 2) - Medium
spyOn allows you to mock either the whole module or the individual functions of the module. At its most general usage, it can...
Read more >
Mock Functions - Jest
Mock functions are also known as "spies", because they let you spy on the behavior of a function that is called indirectly by...
Read more >
How to Mock Using Jest.spyOn (Part 2) - Echobind
You can mock a function with jest.fn or mock a module with jest.mock ... to return the date we set (instead of the...
Read more >
Mocking with Jest: Spying on Functions and Changing ...
Improve your unit testing experience by using Jest to record calls of particular methods and even changing their implementation as needed.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found