Мраморный тест не проходит с Jest, но эквивалентный тест проходит успешно с Jasmine

Я пытаюсь преобразовать свои модульные тесты с Jasmine в Jest. Некоторые тесты начали давать сбой после преобразования их в Jest. Может кто-нибудь объяснить, почему они терпят неудачу с Jest.

Мне удалось выделить проблему в тестовом примере ниже.

С Жасмин проходит успешно:

import { JasmineMarble } from './jasmine-marble';
import { cold } from 'jasmine-marbles';
import { switchMap } from 'rxjs/operators';
import { EMPTY, Observable } from 'rxjs';

class Service {
  foo(): Observable<any> {
    return EMPTY;
  }

  bar(a): Observable<any> {
    return EMPTY;
  }
}

describe('JasmineMarble', () => {
  it('should create an instance', () => {
    const service = new Service();

    spyOn(service, 'foo').and.returnValue(cold('a|', { a: 'A' }));
    spyOn(service, 'bar').and.returnValue(cold('a-b-c|', { a: 'A', b: 'B', c: 'C'}));

    const result$ = service.foo().pipe(switchMap(a => service.bar(a)));

    expect(result$).toBeObservable(cold('a-b-c|', { a: 'A', b: 'B', c: 'C'}));
    expect(service.bar).toHaveBeenCalledWith('A');
  });
});

С Jest это не удается с этой трассировкой ошибки:

expect(jest.fn()).toHaveBeenCalledWith(expected)

Expected mock function to have been called with:
  ["A"]
But it was not called.

Код Jest:

import { JestMarble } from './jest-marble';
import { cold } from 'jest-marbles';
import { switchMap } from 'rxjs/operators';
import { EMPTY, Observable } from 'rxjs';

class Service {
  foo(): Observable<any> {
    return EMPTY;
  }

  bar(a): Observable<any> {
    return EMPTY;
  }
}

describe('JestMarble', () => {
  it('should create an instance', () => {
    const service = new Service();

    jest.spyOn(service, 'foo').mockReturnValue(cold('a|', { a: 'A' }));
    jest.spyOn(service, 'bar').mockReturnValue(cold('a-b-c|', { a: 'A', b: 'B', c: 'C'}));

    const result$ = service.foo().pipe(switchMap(a => service.bar(a)));

    expect(result$).toBeObservable(cold('a-b-c|', { a: 'A', b: 'B', c: 'C'}));
    expect(service.bar).toHaveBeenCalledWith('A');
  });
});

Может кто-нибудь объяснить такое поведение?

Здесь вы можете найти пример репозитория: https://github.com/stijnvn/marbles Пример Jasmine можно запустить с ng test jasmine-marbles. Шутка с ng test jest-marbles.


person stijnvn    schedule 16.04.2019    source источник
comment
В качестве обходного пути я теперь использую жасминовые шарики с Jest. Не уверен, есть ли недостатки.   -  person stijnvn    schedule 18.04.2019
comment
У меня то же самое - после перехода с "jasmine-marbles": "=0.3.1" на "jest-marbles": "=2.3.1" все тесты со шпионами начали терпеть неудачу :(   -  person Felix    schedule 17.05.2019
comment
github.com/meltedspark/jest-marbles/issues/112   -  person Felix    schedule 17.05.2019


Ответы (1)


Теперь toSatisfyOnFlush введены для решения этой проблемы:

describe('JestMarble', () => {
  it('should create an instance', () => {
    const service = new Service();

    jest.spyOn(service, 'foo').mockReturnValue(cold('a|', { a: 'A' }));
    jest.spyOn(service, 'bar').mockReturnValue(cold('a-b-c|', { a: 'A', b: 'B', c: 'C'}));

    const result$ = service.foo().pipe(switchMap(a => service.bar(a)));

    expect(result$).toBeObservable(cold('a-b-c|', { a: 'A', b: 'B', c: 'C'}));
    expect(output$).toSatisfyOnFlush(() => {
      expect(service.bar).toHaveBeenCalledWith('A');
    });
  });
});
person Joe    schedule 17.11.2020