Javascript 如何使用 jasmine 监视 getter 属性?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/33148496/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 14:42:09  来源:igfitidea点击:

How can I spy on a getter property using jasmine?

javascriptjasmine

提问by Ben Aston

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.

This also does not work AFAICT:

这也不起作用 AFAICT:

spyOn(Object.getOwnPropertyDescriptor(o, 'foo'), 'get').and.returnValue('bar');

采纳答案by apsillers

Since Jasmine 2.6, this has been possible with spyOnProperty. To spy on the accessors for the fooproperty, do:

从 Jasmine 2.6 开始,这可以通过spyOnProperty. 要监视foo属性的访问器,请执行以下操作:

spyOnProperty(o, 'foo')

This allows you to replace the setand/or getaccessor functions for an accessor property with a spy function. You can specify or setor getonly as a third argument:

这允许您使用 spy 函数替换访问器属性的set和/或get访问器函数。您可以指定 orsetget仅作为第三个参数:

spyOnProperty(o, 'foo', 'get')

If you are stuck using an earlier version and cannot upgrade for some reason, you may be able to merge the pull request that added this featureinto your local copy of the code.

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

回答by Juan

In February 2017, they merged a PR adding this feature, they released it in April 2017.

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

so to spy on getters/setters you use: const spy = spyOnProperty(myObj, 'myGetterName', 'get');where myObj is your instance, 'myGetterName' is the name of that one defined in your class as get myGetterName() {}and the third param is the type getor set.

所以要监视您使用的 getter/setter: const spy = spyOnProperty(myObj, 'myGetterName', 'get');其中 myObj 是您的实例,'myGetterName' 是您的类中定义的那个的名称,get myGetterName() {}第三个参数是类型getor set

You can use the same assertions that you already use with the spies created with spyOn.

您可以使用与使用spyOn.

So you can for example:

所以你可以例如:

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.

Here's the line in the github source code where this method is available if you are interested.

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

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

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

Answering the original question, with jasmine 2.6.1, you would:

用 jasmine 2.6.1 回答最初的问题,你会:

var o = { get foo() {} };
spyOnProperty(o, 'foo', 'get').and.returnValue('bar');

回答by Aniruddha Das

I think the best way is to use spyOnProperty. It expects 3 properties and you need to pass getor setas third property.

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

spyOnProperty(o, 'foo', 'get').and.returnValue('bar');

回答by AnilRedshift

I took inspiration from @apsillers response and wrote the following helper (requires the prop to be configurable as mentioned above)

我从@apsillers 的回复中获得灵感并编写了以下帮助程序(要求道具如上所述进行配置)

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;
}

And it can be used like so:

它可以像这样使用:

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

Hope it's useful!

希望有用!

回答by George Valentin Iurie?

You can do this if you are unable to use the latest jasmine (2.6.1)

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

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

Documentation for defineProperty, here

defineProperty 的文档,在这里

回答by TwitchBronBron

I don't believe you can spy on getters. The point of a getter is that it acts exactly like a property, so how would jasmine be able to spy on it when it is never called like a function but rather is accessed like a property.

我不相信你可以监视吸气剂。getter 的重点是它的行为完全像一个属性,所以当它从不像函数一样被调用而是像属性一样被访问时,茉莉花如何能够监视它。

As a workaround, you could have your getter call another function and spy on that instead.

作为一种解决方法,您可以让您的 getter 调用另一个函数并监视它。

var o = {
     _foo: function(){
        return 'foo'; 
     }, 
     get foo(){
        return this._foo();
     }
};

spyOn(o, '_foo').and.returnValue('bar');