Конструктор тестирования жасмина, который обещает - PullRequest
0 голосов
/ 17 января 2019

У меня есть сервис, который действует как хранилище данных.В своем конструкторе он пытается «гидрировать» набор данных из хранилища устройства (используя Ionic и его Storage сервис):

@Injectable()
export class SimpleDataStore {

     private _data: BehaviorSubject<any> = new BehaviorSubject<any>(undefined);
     public data: Observable<any> = this._data.asObservable();

     constructor(private _http: HttpClient, private _storage) {
         this.initializeData();
     }

     private initializeData(): void {
          this._storage.get("dataKey")
              .then(data => this._data.next(data))
              .catch(() => this._data.next([]);
     }

}

Я знаю, как писать асинхронные тесты с помощью Jasmine, и какполучить доступ к закрытым членам / методам, а также знать, что нужно проверить _data.getValue() для получения желаемого результата - но моя проблема не в том, как проверить:

  1. Конструктор и / или;
  2. initializeData, так что он ожидает завершения Обещания, поскольку в методе не возвращается Обещание.

Спасибо за любую помощь!

1 Ответ

0 голосов
/ 17 января 2019

В идеале вы должны initializeData() вернуть обещание, которое оно создает, чтобы вы могли легко ждать, пока оно разрешится в ваших тестах. Тогда вместо того, чтобы пытаться выяснить, когда обещание разрешится, вы можете просто высмеять initializeData() до того, как класс будет создан.

Учитывая, что метод initializeData() изменен, чтобы вернуть обещание, вы можете проверить класс SimpleDataStore следующим образом:

describe('SimpleDataStore', function () {

    beforeEach(function () {
        this.initializeData = spyOn(SimpleDataStore.prototype, 'initializeData');
        this.http = jasmine.createSpyObj('HttpClient', ['get']);
        this.storage = jasmine.createSpyObj('Storage', ['get']);
        this.dataStore = new SimpleDataStore(this.http, this.storage);

        // initializeData is called immediately upon construction.
        expect(this.initializeData).toHaveBeenCalled();
    });

    describe('initializeData', function () {

        beforeEach(function () {
            // The data store is initialized, we can now let the calls go to the real implementation.
            this.initializeData.and.callThrough();
        });

        afterEach(function () {
            expect(this.storage.get).toHaveBeenCalledWith('dataKey');
        });

        it('is initialized with "dataKey" storage', function (done) {
            const data = {};
            this.storage.get.and.returnValue(Promise.resolve(data));
            this.dataStore.initializeData()
                .then(() => expect(this.dataStore._data.getValue()).toBe(data))
                .catch(fail)
                .finally(done)
        });

        it('is initialized with empty array when "dataKey" storage rejects', function (done) {
            this.storage.get.and.returnValue(Promise.reject());
            this.dataStore.initializeData()
                .then(() => expect(this.dataStore._data.getValue()).toEqual([]))
                .catch(fail)
                .finally(done)
        });

    });

});
...