简体   繁体   English

使用 Jasmine 在没有 object 的情况下监视 function

[英]Using Jasmine to spy on a function without an object

I'm using Jasmine and have a library js file with lots of functions which are not associated with any object (ie are global).我正在使用 Jasmine 并且有一个库 js 文件,其中包含许多与任何 object(即全局)无关的函数。 How do I go about spying on these functions?我 go 如何监视这些功能?

I tried using window/document as the object, but the spy did not work even though the function was called.我尝试使用窗口/文档作为 object,但即使调用了 function,间谍也没有工作。 I also tried wrapping it in a fake object as follows:我还尝试将其包装在一个假的 object 中,如下所示:

var fakeElement = {};
fakeElement.fakeMethod = myFunctionName;
spyOn(fakeElement, "fakeMethod");

and test with并测试

expect(fakeElement.fakeMethod).toHaveBeenCalled();

This does not work either as the spy did not work.这也不起作用,因为间谍不起作用。

If you are defining your function:如果您正在定义您的功能:

function test() {};

Then, this is equivalent to:那么,这相当于:

window.test = function() {}  /* (in the browser) */

So spyOn(window, 'test') should work.所以spyOn(window, 'test')应该可以工作。

If that is not, you should also be able to:如果不是这样,您还应该能够:

test = jasmine.createSpy();

If none of those are working, something else is going on with your setup.如果这些都不起作用,那么您的设置就会发生其他事情。

I don't think your fakeElement technique works because of what is going on behind the scenes.由于幕后发生的事情,我认为您的fakeElement技术fakeElement The original globalMethod still points to the same code.原来的 globalMethod 仍然指向相同的代码。 What spying does is proxy it, but only in the context of an object.间谍所做的是代理它,但仅在对象的上下文中。 If you can get your test code to call through the fakeElement it would work, but then you'd be able to give up global fns.如果你可以让你的测试代码通过 fakeElement 调用它就会工作,但是你就可以放弃全局 fns。

TypeScript users:打字稿用户:

I know the OP asked about javascript, but for any TypeScript users who come across this who want to spy on an imported function, here's what you can do.我知道 OP 询问了 javascript,但是对于遇到此问题的任何想要监视导入函数的 TypeScript 用户,您可以执行以下操作。

In the test file, convert the import of the function from this:在测试文件中,从这个转换函数的导入:

import {foo} from '../foo_functions';

x = foo(y);

To this:对此:

import * as FooFunctions from '../foo_functions';

x = FooFunctions.foo(y);

Then you can spy on FooFunctions.foo :)然后你可以监视FooFunctions.foo :)

spyOn(FooFunctions, 'foo').and.callFake(...);
// ...
expect(FooFunctions.foo).toHaveBeenCalled();

There is 2 alternative which I use (for jasmine 2)我使用了 2 个替代方案(用于茉莉花 2)

This one is not quite explicit because it seems that the function is actually a fake.这个不是很明确,因为看起来这个函数实际上是一个假的。

test = createSpy().and.callFake(test); 

The second more verbose, more explicit, and "cleaner":第二个更冗长,更明确,“更干净”:

test = createSpy('testSpy', test).and.callThrough();

-> jasmine source code to see the second argument -> jasmine 源码看第二个参数

A very simple way:一个非常简单的方法:

import * as myFunctionContainer from 'whatever-lib';

const fooSpy = spyOn(myFunctionContainer, 'myFunc');

Solution with TypeScript解决方案 TypeScript

Replace your import :替换您的import

import { yourGlobalFunction } from '../your-global-functions';

with:和:

import * as Functions from '../your-global-functions';

Then:然后:

spyOnProperty(Functions, 'yourGlobalFunction').and.returnValue(() => 'mock return value');
import * as saveAsFunctions from 'file-saver';
..........
....... 
let saveAs;
            beforeEach(() => {
                saveAs = jasmine.createSpy('saveAs');
            })
            it('should generate the excel on sample request details page', () => {
                spyOn(saveAsFunctions, 'saveAs').and.callFake(saveAs);
                expect(saveAsFunctions.saveAs).toHaveBeenCalled();
            })

This worked for me.这对我有用。

The approach we usually follow, is as follows :我们通常遵循的方法如下:

utils.ts // file for all global utilities

function globalUtil() {
  // some code
}

abc.component.ts 

function foo {
  // some code
  globalUtil();  // calls global function from util.ts
}

While writing a Jasmine test for function foo () , you can spy on the globalUtil function as follows : 

abc.component.spec.ts

import * as SharedUtilities from 'util.ts';

it('foo', () =>
{
  const globalUtilSpy = jasmine.createSpy('globalUtilSpy');
  spyOnProperty(SharedUtilities, "globalUtilSpy").and.returnValue(globalUtilSpy);
  
  foo();
  expect(globalUtilSpy).toHaveBeenCalled();
});

My answer differs slightly to @FlavorScape in that I had a single (default export) function in the imported module, I did the following:我的答案与 @FlavorScape 略有不同,因为我在导入的模块中有一个(默认导出)函数,我做了以下事情:

import * as functionToTest from 'whatever-lib';

const fooSpy = spyOn(functionToTest, 'default');

我想这是最简单的方法:

const funcSpy = spyOn(myFunc, 'call');

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

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