使用Jasmine监视没有对象的函数


154

我是Jasmine的新手,刚刚开始使用它。我有一个库js文件,其中包含许多未与任何对象关联(即是全局的)的函数。我该如何监视这些功能?

我尝试使用window / document作为对象,但是即使调用了该函数,间谍也无法正常工作。我还尝试将其包装在伪造的对象中,如下所示:

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

并测试

expect(fakeElement.fakeMethod).toHaveBeenCalled();

这也不起作用,因为间谍不起作用

Answers:


155

如果要定义功能:

function test() {};

然后,这等效于:

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

所以spyOn(window, 'test')应该工作。

如果不是这样,您还应该能够:

test = jasmine.createSpy();

如果这些都不起作用,则说明您的设置正在进行其他操作。

我不认为您的fakeElement技术有效是因为幕后情况。原始的globalMethod仍指向相同的代码。间谍所做的是代理它,但仅在对象的上下文中。如果您可以通过fakeElement来调用测试代码,则可以使用该代码,但是您可以放弃全局fns。


2
有效!我认为我之前犯的错误是我用method()而不是method调用了spyOn。谢谢!
Chetter Hummin 2012年

3
由于未分配“窗口”,使用chutzpah使用spyOn(window,'test')进行自动化时遇到一些问题。使用jasmine.createSpy()解决了这个问题。
Henners 2013年

7
jasmine.createSpy()非常适合我。谢谢!
dplass 2014年

1
用于test = jasmine.createSpy();对angularJs间谍$anchroScroll工作完美
埃德加·马丁内斯

1
由于某种原因,我无法使用任何一种方法,但是这完全有可能是因为我正在尝试模拟现有的window函数;$window.open(url, '_blank');旨在打开新标签页(或窗口,具体取决于浏览器设置)。无论如何使用浏览器,我应该如何确保它正在调用此函数并验证它是否在导航到正确的URL?
CSS

71

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();

3
感谢您的TypeScript提示。对于ES6 / Babel应该相同,但是我还没有尝试过。
hgoebl '17

1
似乎只有在使用别名FooFunctions显式调用该函数时,它才有效。我有一个函数bar(),它是一个工厂,返回baz(),并且想要测试baz()调用foo()。在这种情况下,该方法似乎不起作用。
理查德·马特森

4
如果别名是在foo_functions内部获取的, export const FooFunctions = { bar, foo }; 并且在测试中的导入变为有效 import { FooFunctions } from '../foo_functions'. ,则该方法将起作用。但是,仍然需要在foo_functions私有实现中显式使用别名才能使间谍工作。 const result = FooFunctions.foo(params)//间谍报告来电const result = foo(params)//间谍报告没有来电
Richard Matsen

2
像魅力一样工作!谢谢,您节省了我很多时间!
SrAxi

1
这是不工作了有一个Error: <spyOn> : parseCookie is not declared writable or has no setter
凌武

42

我使用2种替代品(用于茉莉2)

这个函数不是很明确,因为它似乎实际上是伪函​​数。

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

第二个更详细,更明确,更“干净”:

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

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


这更有意义,并且将其扩展到足以成功复制的程度。向我+1。谢谢,C§–
CSS

9

一个非常简单的方法:

import * as myFunctionContainer from 'whatever-lib';

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

1
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();
            })

这对我有用。


4
请在您的答案中添加解释,如果代码本身不能理解正在发生的事情,那么代码本身对于问这个问题的人并没有帮助。
chevybow

0

我的答案与@FlavorScape略有不同,因为我在导入的模块中有一个(默认导出)功能,我做了以下工作:

import * as functionToTest from 'whatever-lib';

const fooSpy = spyOn(functionToTest, 'default');
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.