使用Jasmine监视没有对象的函数
Using Jasmine to spy on a function without an object
我正在使用Jasmine,并且有一个库js文件,其中包含许多与任何对象无关的功能(即全局(。如何监视这些功能?
我尝试使用窗口/文档作为对象,但即使调用了该函数,间谍也不起作用。我还尝试将其包装在假物体中,如下所示:
var fakeElement = {};
fakeElement.fakeMethod = myFunctionName;
spyOn(fakeElement, "fakeMethod");
并测试
expect(fakeElement.fakeMethod).toHaveBeenCalled();
这也不起作用,因为间谍不起作用。
如果你正在定义你的函数:
function test() {};
那么,这相当于:
window.test = function() {} /* (in the browser) */
所以spyOn(window, 'test')
应该有效。
如果不是这样,您还应该能够:
test = jasmine.createSpy();
如果这些都不起作用,则您的设置正在发生其他事情。
我不认为你的fakeElement
技术有效,因为幕后发生的事情。原始的 globalMethod 仍然指向相同的代码。间谍所做的是代理它,但仅限于对象的上下文中。如果你能让你的测试代码通过fakeElement调用,它将起作用,但这样你就可以放弃全局fns。
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();
我使用 2 种替代方案(用于茉莉花 2(
这个不是很明确,因为看起来该功能实际上是假的。
test = createSpy().and.callFake(test);
第二个更详细、更明确、更"干净":
test = createSpy('testSpy', test).and.callThrough();
->茉莉花源代码以查看第二个参数
一个非常简单的方法:
import * as myFunctionContainer from 'whatever-lib';
const fooSpy = spyOn(myFunctionContainer, 'myFunc');
使用 TypeScript 的解决方案
更换您的import
:
import { yourGlobalFunction } from '../your-global-functions';
跟:
import * as Functions from '../your-global-functions';
然后:
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();
})
这对我有用。
我们通常遵循的方法如下:
utils.ts
所有全局实用程序的文件:
function globalUtil() {
// some code
}
abc.component.ts
:
function foo {
// some code
globalUtil(); // calls global function from util.ts
}
在为 function foo ()
编写 Jasmine 测试时,您可以按如下方式监视 globalUtil 函数:
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();
});
我的回答与@FlavorScape略有不同,因为我在导入的模块中有一个(默认导出(函数,我做了以下操作:
import * as functionToTest from 'whatever-lib';
const fooSpy = spyOn(functionToTest, 'default');
我找到了一种新的方法,因为建议的解决方案对我不起作用:(所以你可以这样做:
import * as FooFunctions from 'foo-functions';
spyOnProperty(FooFunctions, 'foo').and.returnValue(jasmine.createSpy());
如果你想做callThrough
:
import * as FooFunctions from 'foo-functions';
const originalFn = FooFunctions.foo;
spyOnProperty(FooFunctions, 'foo').and.returnValue(
jasmine.createSpy().and.callFake(originalFn)
);
为了更方便,我做了一个帮手。你可以像这样使用它:
import * as FooFunctions from 'foo-functions';
spyOnFunction(FooFunctions, 'foo'); // to call through
spyOnFunction(FooFunctions, 'foo').and.callFake(...) // to call fake
spyOnFunction(FooFunctions, 'foo').and... // to do something else
以下是帮助程序代码:
function spyOnFunction<T, K extends keyof T>(source: T, originalFnKey: K): jasmine.Spy {
const originalFn: T[K] = source[originalFnKey];
if (!isFunction(originalFn)) {
throw new Error('[spyOnFunction] spy target must be a function');
}
const spy: jasmine.Spy = jasmine.createSpy().and.callFake(originalFn);
spyOnProperty(source, originalFnKey).and.returnValue(spy);
return spy;
}
function isFunction(item: unknown): item is (...args: unknown[]) => unknown {
return typeof item === 'function';
}
我想这是最简单的方法:
const funcSpy = spyOn(myFunc, 'call');
- 创建对象函数原型和代码是错误的
- JavaScript模块模式-如何在使用对象/函数之前激发构造函数/init函数
- 如何从onclick字符串中引用javascript对象函数
- 更改对象函数仅用于示例
- javascript和jQuery的嵌套对象函数中的变量范围
- 将对象函数传递给请求动画帧时丢失对象引用
- 对象函数返回函数而不是值
- 使用onclick调用属性对象函数
- javascript拉斐尔对象函数传递
- 如何从onClick事件调用对象函数
- 可以't获取具有“t”的对象变量;这个“;由setTimeout()函数调用的对象函数中的属性
- 对象没有't继承父对象函数
- 调用父对象函数
- "这个“;对象函数内部的引用
- 将变量添加到对象函数调用的末尾
- 传单错误:对象函数没有方法'createIcon'在LayerGroup中创建自定义图标标记时
- TypeError:对象函数Object(){〔本机代码〕}没有方法'方法'
- 挖空 - 单击绑定到对象函数 - 范围问题
- 类型错误: 对象函数...没有方法“打开”
- JavaScript 对象函数