【问题标题】:How can I mock fromEvent function from RXJS 5.5.6?如何从 RXJS 5.5.6 模拟 fromEvent 函数?
【发布时间】:2018-07-03 09:43:18
【问题描述】:

我必须测试一个使用 fromEvent 可观察函数的函数。 在升级到“可出租”运营商之前,我只是这样做:

spyOn(Observable, 'fromEvent').and.callFake(mockFromEventFunction)

但是现在,Rxjs 变了,Observable.fromEvent 只是一个名为 fromEvent 的函数,它是这样导入的:(并且使用方式相同)

import { fromEvent } from 'rxjs/observable/fromEvent';

我的问题是,如何在不知道其父上下文的情况下使用 Jasmine 间谍实用程序模拟该函数?

我建议这不起作用:

import * as FromEventContext from 'rxjs/observable/fromEvent';
...
spyOn(FromEventContext , 'fromEvent').and.callFake(mockFromEventFunction)

现在我有一个解决方法,将 fromEvent 包装在一个我知道上下文的对象中。但我想知道如何干净利落地解决这个问题。

提前致谢。

【问题讨论】:

  • 大概可以从事件测试文件中查看rxjs,看看有没有什么有用的? reactivex.io/rxjs/test-file/spec-js/observables/…
  • 谢谢,但它没有多大帮助......他们在这里测试该功能,但我想模拟它,而不是测试它。
  • 我也有同样的问题。有什么帮助吗?

标签: angular unit-testing jasmine rxjs5 rxjs6


【解决方案1】:

经过一番调查,我发现我们能否模拟这个单一的导出函数这一事实直接取决于我们的打包程序在测试时如何解析模块。

因此,例如,您可能会偶然发现此错误或类似错误:

Error: : myFunctionName is not declared writable or has no setter

因为捆绑器只是将那些孤立的导出函数包装到一个 getter 属性中,使它们无法模拟。

我最终使用的解决方案是在测试时编译'commonjs'中的模块

例如,如果您正在使用 typescript,则需要更改您的 tsconfig.spec.ts 以使用 commonjs 模块:

"compilerOptions": {
     ....
      // force commonjs module output, since it let mock exported members on modules to anywhere in the application (even in the same file)
      "module": "commonjs",
  },

commonjs 中模块的任何导出成员的结果输出将类似于:exports.myFunc = function() {}。这导致使用 spyOn 无需担心,因为它被包裹在“出口”对象上。一个很好的用例是它可以在任何地方被模拟,包括它自己文件中的用法

例子:

// some-module.js
export function functionToMock() {
     return 'myFuncToMock';
}
export function functionToTest() {
     return functionToMock();
}

// testing-module.spec.js
import * as SomeModule from ./some-module
spyOn(SomeModule, 'functionToMock').and.returnValue('mockedCorrectly');
SomeModule.functionToTest().toBe('mockedCorrectly')

【讨论】:

    【解决方案2】:

    你是对的。 FromEventContext 对此不起作用。

    相反,您可以使用 jasmine-auto-spies,这样会更容易处理此类事情。

    import { Spy, createSpyFromClass } from 'jasmine-auto-spies';
    

    在您的测试代码中,您现在可以在 Observables 上创建间谍:

    fakeObservable = createSpyFromClass(Observable);
    fakeObservable.fromEvent.and.returnValue(Observable.empty()) // or whatever you want to return
    

    也许这有帮助?!

    【讨论】:

    • 嗨 André,在我的场景中,没有 Observable 类。 fromEvent 只是一个函数,它不像 Observable.fromEvent 那样来自 Observable 类......所以这个解决方案将不起作用。如果我没记错的话,这和 spyOn 是一样的。
    【解决方案3】:

    不知道是不是你的情况,但如果你在fromEventspyOnProperty 它可能会起作用。

    像这样:

    spyOnProperty(rxjs, 'fromEvent').and.returnValue(() => rxjs.of({}));
    

    在我的例子中,我导入了整个 rxjs

    import * as rxjs from 'rxjs';
    

    希望对你有帮助, 干杯!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-06
      • 1970-01-01
      • 2018-01-11
      • 1970-01-01
      • 1970-01-01
      • 2018-10-30
      相关资源
      最近更新 更多