hirezio / auto-spies

Create automatic spies from classes
MIT License
180 stars 30 forks source link

Cannot read property '_isRejectedPromise' of null #38

Closed flowest closed 3 years ago

flowest commented 3 years ago

When using calledWith, i get the error:

image

Spec file:

import { HttpClient } from '@angular/common/http';
import { NO_ERRORS_SCHEMA } from '@angular/core';
import { async, TestBed } from '@angular/core/testing';
import { StorageType } from 'app/models/storage-types';
import { StorageService } from 'app/shared/services/storage.service';
import { de } from 'assets/i18n/de';
import { en } from 'assets/i18n/en';
import { createSpyFromClass, Spy } from 'jasmine-auto-spies';
import { TranslateTestingModule } from 'ngx-translate-testing';
import { SmsRecipientsCostHelperService } from '../sms-recipients-cost-dialog/sms-recipients-cost-helper.service';

const SmsRecipientsCostDialogStorageKey = 'sms-recipients-cost-dialog';

describe('SmsRecipientsCostHelperService', () => {
    let serviceUnderTest: SmsRecipientsCostHelperService;

    let storageServiceSpy: Spy<StorageService>;

    const mocksInjected: Array<{ provide: any, useValue: any }> = [
        { provide: StorageService, useValue: createSpyFromClass(StorageService) },
    ];

    const configureTestBed = () => {
        TestBed.configureTestingModule({
            imports: [
                TranslateTestingModule.withTranslations(
                    { en: en, de: de }
                )
            ],
            providers: [...mocksInjected, SmsRecipientsCostHelperService],
            schemas: [NO_ERRORS_SCHEMA]
        })
            .compileComponents();
    };

    const setupDefaultMockBehaviour = () => {
    };

    const setFixtureAndComponentUnderTest = () => {
        serviceUnderTest = TestBed.inject(SmsRecipientsCostHelperService);
    };

    describe('when it gets initialized', () => {
        beforeEach(async(configureTestBed));
        beforeEach(setupDefaultMockBehaviour);
        beforeEach(setFixtureAndComponentUnderTest);

        it('should create', () => {
            expect(serviceUnderTest).toBeTruthy();
        });
    });

    describe('when local storage is empty', () => {
        beforeEach(async(configureTestBed));
        beforeEach(setupDefaultMockBehaviour);
        beforeEach(setFixtureAndComponentUnderTest);

        beforeEach(() => {
            storageServiceSpy = TestBed.inject<any>(StorageService);

            storageServiceSpy
                .getValue
                .calledWith(SmsRecipientsCostDialogStorageKey, StorageType.Local)
                .returnValue(null);
        });

        it('#isCostDialogNeededToBeShown should return true', () => {
            expect(serviceUnderTest.isCostDialogNeededToBeShown()).toEqual(true);
        });
    });

});

Service to test

import { Injectable } from '@angular/core';
import { StorageType } from '../../models/storage-types';
@Injectable({
  providedIn: 'root'
})
export class StorageService {
  constructor() { }

...

  public getValue(
    key: string,
    storageType: StorageType = StorageType.Session
  ): string | null {
    if (storageType === StorageType.Local) {
      return window.localStorage.getItem(key);
    } else {
      if (this.isSessionStorageSupport) {
        return window.sessionStorage.getItem(key);
      } else {
        return window.localStorage.getItem(key);
      }
    }
  }
}

As soon as I replace .calledWith(SmsRecipientsCostDialogStorageKey, StorageType.Local) with a simple and it works...

What am I doing wrong?

shairez commented 3 years ago

Thanks for the report @flowest !

Congrats, you found a bug! 😀

I just fixed it so you should not see this behavior in the latest version

Thanks!