javascript - Jest 的 Marble 测试失败,但 Jasmine 的等效测试成功

标签 javascript jasmine jestjs jasmine-marbles

我正在尝试将我的单元测试从 Jasmine 转换为 Jest。一些测试在将它们转换为 Jest 后开始失败。有人可以解释为什么他们在 Jest 上失败了。

我设法将问题隔离到下面的测试用例中。

随着 Jasmine 运行成功:

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 的 Jest .

最佳答案

现在有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');
    });
  });
});

关于javascript - Jest 的 Marble 测试失败,但 Jasmine 的等效测试成功,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55705040/

相关文章:

node.js - 创建 jest.config.file 的指南

node.js - 如何在 Jest 中监视导出和模拟的函数

reactjs - enzyme 无法通过构造函数选择器找到,但通过显示名称选择器成功找到

javascript - 这些片段有什么区别?

javascript - 在 panendhammer.js 上获取平移方向并限制方向

javascript - 将图像文件夹上传到 Firestore 存储并将下载 URL 放入 Firestore

angularjs - 写好 App 后再写 Angular 单元测试?

javascript - Jasmine /Mocha 咕噜声 : accessing tests on filesystem or through webserver?

angular - 将 jasmie .toHaveBeenCalledWith() 函数与 Moment 对象一起使用

javascript - 将 blob 附加到表单中类型文件的输入