简体   繁体   English

如何从 RXJS 5.5.6 模拟 fromEvent 函数?

[英]How can I mock fromEvent function from RXJS 5.5.6?

I have to test a function that uses the fromEvent observable function.我必须测试一个使用fromEvent observable 函数的函数。 Before the upgrade to 'lettable' operators, I was just doing this:在升级到“可出租”运营商之前,我只是这样做:

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

But now, Rxjs have changed, and Observable.fromEvent is just a function named fromEvent , that is imported like this: (and used the same way)但是现在,Rxjs 发生了变化, Observable.fromEvent只是一个名为fromEvent的函数,它是这样导入的:(并以相同的方式使用)

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

My question is, how I can mock that function with Jasmine spy utilities without knowing it's parent context?我的问题是,如何在不知道其父上下文的情况下使用 Jasmine 间谍实用程序模拟该函数?

I advise that this doesn't work:我建议这不起作用:

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

Now I have a workaround wrapping that fromEvent in one Object which I know the context.现在我有一种解决方法,将 fromEvent 包装在一个我知道上下文的对象中。 But I am wondering how I can solve this cleanly.但我想知道如何干净地解决这个问题。

Thanks in advance.提前致谢。

After some investigation I discovered that the fact that we can or cannot mock this single exported functions is directly dependen in how our bundler resolves the modules when testing.经过一些调查,我发现我们可以或不能模拟这个单个导出函数的事实直接取决于我们的打包器在测试时如何解析模块。

So for example, you may stumble to this error or similarly:因此,例如,您可能会遇到此错误或类似的错误:

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

Caused because the bundler just wrapped those lonely exported functions into a getter property, making them impossible to mock.这是因为打包器只是将那些孤立的导出函数包装到一个 getter 属性中,使它们无法模拟。

The solution that I ended using is compile modules in 'commonjs' when testing.我结束使用的解决方案是在测试时'commonjs'编译模块

For example, if you are working with typescript, you would need to change change your tsconfig.spec.ts to use commonjs module:例如,如果您正在使用 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",
  },

The resultant output of any exported member of a module in commonjs would be like: exports.myFunc = function() {} . commonjs 中模块的任何导出成员的结果输出将类似于:exports.myFunc exports.myFunc = function() {} This led use spyOn without worries since it is wrapped on the 'exports' object.这导致使用 spyOn 无需担心,因为它被包裹在 'exports' 对象上。 One great use case of that, is that it would be mocked anywhere, including the usages in its own file !一个很好的用例是它可以在任何地方被嘲笑,包括它自己文件中的用法

Example:示例:

// 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')

You are right.你是对的。 FromEventContext does not work for that. FromEventContext 对此不起作用。

Instead you could use jasmine-auto-spies, that would make it easier to handle such things.相反,您可以使用 jasmine-auto-spies,这样可以更轻松地处理此类事情。

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

In your test-code you can now create spies on Observables:在您的测试代码中,您现在可以在 Observables 上创建间谍:

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

Maybe this helps?!也许这有帮助?!

Don't know if its your case, but if you spyOnProperty on fromEvent it may work.不知道这是否是您的情况,但是如果您在spyOnPropertyfromEvent它可能会起作用。

Like this:像这样:

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

In my case I import the entire rxjs library就我而言,我导入了整个rxjs

import * as rxjs from 'rxjs';

Hope it helps, Cheers!希望它有帮助,干杯!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM