用 Jasmine 监视一个没有对象的函数

我刚接触茉莉花,刚开始使用它。我有一个包含许多函数的库 js 文件,这些函数与任何对象都没有关联(即是全局的)。我如何监视这些功能?

我尝试使用 window/document 作为对象,但是即使调用了该函数,间谍也无法工作。我还试着用一个假的东西把它包起来,如下所示:

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

测试

expect(fakeElement.fakeMethod).toHaveBeenCalled();

这也没有工作,因为间谍没有工作

143439 次浏览

如果你正在定义你的功能:

function test() {};

那么,这相当于:

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

所以 spyOn(window, 'test')应该能行。

如果不是,你也应该能够:

test = jasmine.createSpy();

如果这些都不起作用,那么您的设置就出现了其他问题。

我不认为你的 fakeElement技术工作,因为什么是幕后发生的事情。原来的 globalMethod 仍然指向相同的代码。间谍所做的就是代理它,但只是在一个对象的上下文中。如果您可以让您的测试代码通过 fakeElement 调用,那么它就可以工作,但是之后您就可以放弃全局 fns。

我有两种选择(茉莉花2)

这个函数并不十分明确,因为它看起来实际上是一个伪函数。

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

第二个更冗长、更明确、更“干净”:

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

- > 茉莉花的源代码查看第二个参数

TypeScript 用户:

我知道 OP 询问了关于 javascript 的问题,但是对于任何想要监视导入函数的 TypeScript 用户来说,以下是您可以做的事情。

在测试文件中,将函数的导入转换为:

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


x = foo(y);

这样说:

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


x = FooFunctions.foo(y);

然后你可以监视 FooFunctions.foo:)

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

一个非常简单的方法:

import * as myFunctionContainer from 'whatever-lib';


const fooSpy = spyOn(myFunctionContainer, 'myFunc');
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();
})

这招对我很管用。

我的回答与@FlavorScape 稍有不同,因为我在导入的模块中有一个单一的(默认导出)函数,我做了以下操作:

import * as functionToTest from 'whatever-lib';


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

我们通常遵循的方法如下:

所有全球公用事业的 utils.ts文件:

function globalUtil() {
// some code
}

返回文章页面

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

在为 function foo ()编写 Jasmine 测试时,您可以像下面这样监视 globalUtil 函数:

返回文章页面

import * as SharedUtilities from 'util.ts';


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

foo();
expect(globalUtilSpy).toHaveBeenCalled();
});

我想这是最简单的方法:

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

使用 TypeScript 解决方案

更换你的 import:

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

与:

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

然后:

spyOnProperty(Functions, 'yourGlobalFunction').and.returnValue(() => 'mock return value');