10

我必须测试一个使用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 包装在一个我知道上下文的对象中。但我想知道如何干净地解决这个问题。

提前致谢。

4

3 回答 3

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')
于 2020-10-28T10:04:44.743 回答
0

不知道是不是你的情况,但如果你spyOnProperty这样fromEvent做可能会奏效。

像这样:

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

就我而言,我导入了整个rxjs

import * as rxjs from 'rxjs';

希望它有帮助,干杯!

于 2019-11-08T13:57:22.927 回答
0

You are right. FromEventContext does not work for that.

Instead you could use jasmine-auto-spies, that would make it easier to handle such things.

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

In your test-code you can now create spies on Observables:

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

Maybe this helps?!

于 2018-07-14T09:23:25.947 回答