admin管理员组

文章数量:1310431

I need to test whether or not the logger() function is called in the addCampus method I am testing when it throws an error. I am fairly new to jest so I may be missing something simple

Logger.js

function logger(level, message) {
//logs message to console
//has no explicit return
}

export default logger;

AddCampusList.jsx

import logger from '../../Logger';
addCampus = campus => {
    axios
      .post('/api/campuses/', {
        name: campus.campusName,
        abbreviation: campus.campusAbbreviation,
      })
      .then(response => {
        const { campuses } = this.state;
        campuses.push(response.data);
        this.setState({ campuses });
      })
      .catch(error => {
        this.props.displayError(error);
        logger('ERROR', error);
      });
  };

AddCampusList.test.js

import logger from '../../../src/Logger.js'
...
it('calls displayError() with error', async () => {
      getSpy = jest.spyOn(axios, 'get').mockRejectedValueOnce(error);
      const logger = jest.fn();
      const loggerSpy = jest.spyOn(logger, 'default');
      wrapper = await shallow(<AddCampusList
        displayError={displayError}
        onSelectCampus={onSelectCampus}
        selectedCampus={selectedCampus}
        isMobileViewport={isMobileViewport}
      />);

      expect(displayError).toHaveBeenCalledWith(error);
      expect(loggerSpy).toHaveBeenCalled();
    });

The expect(displayError) is working properly, but the expect(loggerSpy) is not. I have tried several different things, but this is the error I have run into most often

 Cannot spy the default property because it is not a function; undefined given instead
> 105 |       const loggerSpy = jest.spyOn(logger, 'default');

I need to test whether or not the logger() function is called in the addCampus method I am testing when it throws an error. I am fairly new to jest so I may be missing something simple

Logger.js

function logger(level, message) {
//logs message to console
//has no explicit return
}

export default logger;

AddCampusList.jsx

import logger from '../../Logger';
addCampus = campus => {
    axios
      .post('/api/campuses/', {
        name: campus.campusName,
        abbreviation: campus.campusAbbreviation,
      })
      .then(response => {
        const { campuses } = this.state;
        campuses.push(response.data);
        this.setState({ campuses });
      })
      .catch(error => {
        this.props.displayError(error);
        logger('ERROR', error);
      });
  };

AddCampusList.test.js

import logger from '../../../src/Logger.js'
...
it('calls displayError() with error', async () => {
      getSpy = jest.spyOn(axios, 'get').mockRejectedValueOnce(error);
      const logger = jest.fn();
      const loggerSpy = jest.spyOn(logger, 'default');
      wrapper = await shallow(<AddCampusList
        displayError={displayError}
        onSelectCampus={onSelectCampus}
        selectedCampus={selectedCampus}
        isMobileViewport={isMobileViewport}
      />);

      expect(displayError).toHaveBeenCalledWith(error);
      expect(loggerSpy).toHaveBeenCalled();
    });

The expect(displayError) is working properly, but the expect(loggerSpy) is not. I have tried several different things, but this is the error I have run into most often

 Cannot spy the default property because it is not a function; undefined given instead
> 105 |       const loggerSpy = jest.spyOn(logger, 'default');
Share Improve this question edited Sep 3, 2020 at 15:55 Cameron K asked Sep 3, 2020 at 15:15 Cameron KCameron K 632 silver badges6 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 7

The package logger is already default import so it's not supposed to have default property.

A correct way to spy on it is:

import * as loggerMod from '../../../src/Logger'
...
const loggerSpy = jest.spyOn(loggerMod, 'default');

This may not work because ES modules are read-only and whether this is enforced depends on a setup.

A more correct way is to do this in module mock:

import logger from '../../../src/Logger'

jest.mock('../../../src/Logger.js', () => {
  const loggerMod = jest.requireActual('../../../src/Logger');

  return {
    ...loggerMod,
    __esModule: true,
    default: jest.fn(loggerMod.default)
  };
});

...

expect(logger).toHaveBeenCalled();

Most times it's preferable to mock a function that does potentially undesirable side effects rather than spy on it, and this is much simpler, especially for a module with default export only:

jest.mock('../../../src/Logger', () => jest.fn());

本文标签: javascriptSpy on default exported function with JestStack Overflow