我如何使用 jasmine 监视 getter 属性?
How can I spy on a getter property using jasmine?
如何使用 jasmine 监视 getter 属性?
var o = { get foo() {}, };
spyOn(o, 'foo').and.returnValue('bar'); // Doesn't work.
这也不起作用 AFAICT:
spyOn(Object.getOwnPropertyDescriptor(o, 'foo'), 'get').and.returnValue('bar');
我不相信你可以监视 getters。 getter 的要点在于它的行为与 属性 完全相同,因此当它从未像函数那样被调用而是像 属性 那样被访问时,jasmine 如何能够监视它].
作为解决方法,您可以让 getter 调用另一个函数并监视它。
var o = {
_foo: function(){
return 'foo';
},
get foo(){
return this._foo();
}
};
spyOn(o, '_foo').and.returnValue('bar');
从 Jasmine 2.6 开始,spyOnProperty
就可以做到这一点。要监视 foo
属性 的访问器,请执行:
spyOnProperty(o, 'foo')
这允许您用间谍函数替换访问器 属性 的 set
and/or get
访问器函数。您只能将 or set
或 get
指定为第三个参数:
spyOnProperty(o, 'foo', 'get')
如果您无法使用早期版本并且由于某种原因无法升级,您可以将 pull request that added this feature 合并到您的本地代码副本中。
我从@apsillers 的回复中获得灵感并编写了以下帮助程序(需要 prop 如上所述可配置)
let activeSpies = [];
let handlerInstalled = false;
function afterHandler() {
activeSpies.forEach(({ obj, prop, descriptor }) => Object.defineProperty(obj, prop, descriptor));
activeSpies = [];
}
export function spyOnGetter(obj, prop) {
const env = jasmine.getEnv();
const descriptor = Object.getOwnPropertyDescriptor(obj, prop);
const spy = jasmine.createSpy(`${prop} spy`);
const copy = Object.assign({}, descriptor, { get: spy });
Object.defineProperty(obj, prop, copy);
activeSpies.push({
obj,
prop,
descriptor,
});
if (!handlerInstalled) {
handlerInstalled = true;
env.afterEach(() => afterHandler());
}
return spy;
}
并且可以这样使用:
import { spyOnGetter } from spyExtra;
it('tests the thing', () => {
spyOnGetter(myObj, 'myProp').and.returnValue(42);
expect(myObj.myProp).toBe(42);
});
希望有用!
2017 年 2 月,他们合并了一个添加此功能的 PR,他们于 2017 年 4 月发布了它。
所以要监视 getters/setters 你使用:
const spy = spyOnProperty(myObj, 'myGetterName', 'get');
其中 myObj 是您的实例,'myGetterName' 是在您的 class 中定义为 get myGetterName() {}
的实例的名称,第三个参数是类型 get
或 set
。
您可以使用与 spyOn
创建的间谍相同的断言。
所以你可以例如:
const spy = spyOnProperty(myObj, 'myGetterName', 'get'); // to stub and return nothing. Just spy and stub.
const spy = spyOnProperty(myObj, 'myGetterName', 'get').and.returnValue(1); // to stub and return 1 or any value as needed.
const spy = spyOnProperty(myObj, 'myGetterName', 'get').and.callThrough(); // Call the real thing.
这是 github 源代码中的一行,如果您有兴趣可以使用此方法。
回答最初的问题,使用 jasmine 2.6.1,您将:
var o = { get foo() {} };
spyOnProperty(o, 'foo', 'get').and.returnValue('bar');
如果您无法使用最新的 jasmine (2.6.1),您可以这样做
const getSpy = jasmine.createSpy().and.returnValue('bar')
Object.defineProperty(o, 'foo', { get: getSpy });
defineProperty 的文档,here
我认为最好的方法是使用spyOnProperty
。它需要 3 个属性,您需要将 get
或 set
作为第三个 属性.
spyOnProperty(o, 'foo', 'get').and.returnValue('bar');
如何使用 jasmine 监视 getter 属性?
var o = { get foo() {}, };
spyOn(o, 'foo').and.returnValue('bar'); // Doesn't work.
这也不起作用 AFAICT:
spyOn(Object.getOwnPropertyDescriptor(o, 'foo'), 'get').and.returnValue('bar');
我不相信你可以监视 getters。 getter 的要点在于它的行为与 属性 完全相同,因此当它从未像函数那样被调用而是像 属性 那样被访问时,jasmine 如何能够监视它].
作为解决方法,您可以让 getter 调用另一个函数并监视它。
var o = {
_foo: function(){
return 'foo';
},
get foo(){
return this._foo();
}
};
spyOn(o, '_foo').and.returnValue('bar');
从 Jasmine 2.6 开始,spyOnProperty
就可以做到这一点。要监视 foo
属性 的访问器,请执行:
spyOnProperty(o, 'foo')
这允许您用间谍函数替换访问器 属性 的 set
and/or get
访问器函数。您只能将 or set
或 get
指定为第三个参数:
spyOnProperty(o, 'foo', 'get')
如果您无法使用早期版本并且由于某种原因无法升级,您可以将 pull request that added this feature 合并到您的本地代码副本中。
我从@apsillers 的回复中获得灵感并编写了以下帮助程序(需要 prop 如上所述可配置)
let activeSpies = [];
let handlerInstalled = false;
function afterHandler() {
activeSpies.forEach(({ obj, prop, descriptor }) => Object.defineProperty(obj, prop, descriptor));
activeSpies = [];
}
export function spyOnGetter(obj, prop) {
const env = jasmine.getEnv();
const descriptor = Object.getOwnPropertyDescriptor(obj, prop);
const spy = jasmine.createSpy(`${prop} spy`);
const copy = Object.assign({}, descriptor, { get: spy });
Object.defineProperty(obj, prop, copy);
activeSpies.push({
obj,
prop,
descriptor,
});
if (!handlerInstalled) {
handlerInstalled = true;
env.afterEach(() => afterHandler());
}
return spy;
}
并且可以这样使用:
import { spyOnGetter } from spyExtra;
it('tests the thing', () => {
spyOnGetter(myObj, 'myProp').and.returnValue(42);
expect(myObj.myProp).toBe(42);
});
希望有用!
2017 年 2 月,他们合并了一个添加此功能的 PR,他们于 2017 年 4 月发布了它。
所以要监视 getters/setters 你使用:
const spy = spyOnProperty(myObj, 'myGetterName', 'get');
其中 myObj 是您的实例,'myGetterName' 是在您的 class 中定义为 get myGetterName() {}
的实例的名称,第三个参数是类型 get
或 set
。
您可以使用与 spyOn
创建的间谍相同的断言。
所以你可以例如:
const spy = spyOnProperty(myObj, 'myGetterName', 'get'); // to stub and return nothing. Just spy and stub.
const spy = spyOnProperty(myObj, 'myGetterName', 'get').and.returnValue(1); // to stub and return 1 or any value as needed.
const spy = spyOnProperty(myObj, 'myGetterName', 'get').and.callThrough(); // Call the real thing.
这是 github 源代码中的一行,如果您有兴趣可以使用此方法。
回答最初的问题,使用 jasmine 2.6.1,您将:
var o = { get foo() {} };
spyOnProperty(o, 'foo', 'get').and.returnValue('bar');
如果您无法使用最新的 jasmine (2.6.1),您可以这样做
const getSpy = jasmine.createSpy().and.returnValue('bar')
Object.defineProperty(o, 'foo', { get: getSpy });
defineProperty 的文档,here
我认为最好的方法是使用spyOnProperty
。它需要 3 个属性,您需要将 get
或 set
作为第三个 属性.
spyOnProperty(o, 'foo', 'get').and.returnValue('bar');