我如何使用茉莉花来监视getter属性?

Ben*_*Ben 45 javascript jasmine

我如何使用茉莉花来监视getter属性?

var o = { get foo() {}, };

spyOn(o, 'foo').and.returnValue('bar'); // Doesn't work.
Run Code Online (Sandbox Code Playgroud)

这也不起作用AFAICT:

spyOn(Object.getOwnPropertyDescriptor(o, 'foo'), 'get').and.returnValue('bar');
Run Code Online (Sandbox Code Playgroud)

aps*_*ers 42

从Jasmine 2.6开始,这已经成为可能了spyOnProperty.要监视该foo属性的访问者,请执行以下操作:

spyOnProperty(o, 'foo')
Run Code Online (Sandbox Code Playgroud)

这允许您使用间谍函数替换访问器属性的set和/或get访问器函数.您可以指定或setget只作为第三个参数:

spyOnProperty(o, 'foo', 'get')
Run Code Online (Sandbox Code Playgroud)

如果您因使用早期版本而无法升级并且由于某种原因无法升级,则可以将添加此功能拉取请求合并到您的本地代码副本中.

  • 如果`accessor`没有设置为`configurable:true`,我是否认为这会失败?这意味着如果你试图监视没有指定的第三方访问者,那你就不走运了? (3认同)

Jua*_*uan 24

2017年2月,他们合并了PR添加此功能,他们于2017年4月发布.

所以要监视你使用的getter/setter: const spy = spyOnProperty(myObj, 'myGetterName', 'get'); myObj是你的实例,'myGetterName'是你的类中定义的名称,get myGetterName() {}第三个param是类型getset.

您可以使用已经与创建的间谍一起使用的相同断言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.
Run Code Online (Sandbox Code Playgroud)

这是github源代码中的行,如果您感兴趣,可以使用此方法.

https://github.com/jasmine/jasmine/blob/7f8f2b5e7a7af70d7f6b629331eb6fe0a7cb9279/src/core/requireInterface.js#L199

用jasmine 2.6.1回答原来的问题,你会:

var o = { get foo() {} };
spyOnProperty(o, 'foo', 'get').and.returnValue('bar');
Run Code Online (Sandbox Code Playgroud)


Geo*_*ieţ 6

如果您无法使用最新的 jasmine (2.6.1),您可以这样做

const getSpy = jasmine.createSpy().and.returnValue('bar')
Object.defineProperty(o, 'foo', { get: getSpy });
Run Code Online (Sandbox Code Playgroud)

defineProperty 的文档,在这里


Ani*_*ift 5

我从@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;
}
Run Code Online (Sandbox Code Playgroud)

它可以像这样使用:

import { spyOnGetter } from spyExtra;
it('tests the thing', () => {
    spyOnGetter(myObj, 'myProp').and.returnValue(42);
    expect(myObj.myProp).toBe(42);
});
Run Code Online (Sandbox Code Playgroud)

希望它有用!


Ani*_*Das 5

我认为最好的方法是使用spyOnProperty。它需要3个属性,您需要通过getset作为第三个属性。

spyOnProperty(o, 'foo', 'get').and.returnValue('bar');
Run Code Online (Sandbox Code Playgroud)