Search code examples
angularjasminejestjsangular-cliangular-jest

Angular 8 with Jest - 'jasmine' has no exported member 'SpyObj'


I have an Angular CLI project that has the default Karma test runner. I used this tutorial to replace Karma with Jest and notice some tests are passing some failing.

For example, declaring a variable on test level:

let mockObj: jasmine.SpyObj<MyClass>;

throws the error:

error `"Namespace 'jasmine' has no exported member 'SpyObj'`
@angular-builders/jest: "^8.3.2"
jest: "^24.9.0"
jasmine-core: "3.5.0"
@types/jest: "^24.9.0"
@types/jasmine: "3.5.0"
@types/jasminewd2": "2.0.8"

Solution

  • You have to use Jest spies and mocks instead of Jasmine spies when you choose Jest. Or some other test double library like Sinon.

    Jest class mock example

    import SoundPlayer from './sound-player';
    
    const mockPlaySoundFile = jest.fn();
    jest.mock('./sound-player', () => {
      return jest.fn().mockImplementation(() => {
        return {playSoundFile: mockPlaySoundFile};
      });
    });
    
    beforeEach(() => {
      SoundPlayer.mockClear();
      mockPlaySoundFile.mockClear();
    });
    
    it('The consumer should be able to call new() on SoundPlayer', () => {
      const soundPlayerConsumer = new SoundPlayerConsumer();
      // Ensure constructor created the object:
      expect(soundPlayerConsumer).toBeTruthy();
    });
    
    it('We can check if the consumer called the class constructor', () => {
      const soundPlayerConsumer = new SoundPlayerConsumer();
      expect(SoundPlayer).toHaveBeenCalledTimes(1);
    });
    
    it('We can check if the consumer called a method on the class instance', () => {
      const soundPlayerConsumer = new SoundPlayerConsumer();
      const coolSoundFileName = 'song.mp3';
      soundPlayerConsumer.playSomethingCool();
      expect(mockPlaySoundFile.mock.calls[0][0]).toEqual(coolSoundFileName);
    });