jasmine.createSpyObj 与属性

jasmine.createSpyObj with properties(jasmine.createSpyObj 与属性)
本文介绍了jasmine.createSpyObj 与属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

在我的 Angular 测试中模拟依赖项时,我通常使用 jasmine.createSpyObj 创建一个间谍对象:

When mocking dependencies in my Angular tests, I usually create a spy object using jasmine.createSpyObj:

const serviceSpy= jasmine.createSpyObj('MyService', ['method']);

然后将其提供给 TestBed:

then provide it to the TestBed:

  providers: [
    {provide: MyService, useValue: serviceSpy}
  ]

当我在测试中使用它时,我可以指定所需的返回值:

When I use it in my test, I can then specify the desired return value:

serviceSpy.method.and.returnValue(of([...]));

现在我还需要模拟属性,但我不知道应该怎么做.createSpyObj 确实允许定义属性名称:

Now I also need to mock properties and I cannot find out how it should be done. createSpyObj does allow the definition of property names:

const serviceSpy= jasmine.createSpyObj('MyService', ['method'], ['property']);

但我根据大量文章和答案尝试了不同的解决方案,但没有任何成功,例如:

but I've tried varies solutions based on the numerous articles and answers out there without any success, e.g.:

// Cannot read property 'and' of undefined    
serviceSpy.property.and.returnValue(true);  
// not declared configurable
spyOnProperty(serviceSpy, 'property').and.returnValue(true);  
// no build errors, but value stays 'undefined'
serviceSpy.property = true;  

我可以让它工作一半"的唯一方法是:

The only way I could make it 'half' work is:

let fakeValue = true;
const serviceSpy= jasmine.createSpyObj('MyService', ['method'], {'property': fakeValue});

这里的问题是它在创建时是一次性的.如果我想更改测试中的期望值,它不起作用.

The problem here is that it's a one-time set at creation. If I want to change the expected value in the test, it does not work.

fakeValue = false;
serviceSpy.property ==> stays to the initial value 'true';

是否存在通过创建 spy 对象来模拟方法和属性的解决方案,或者我应该创建自己的假类,然后我可以在其上使用 spyOnspyOnProperty?

Does there exist a solution to both mock methods and properties by creating a spy object, or should I create my own fake class on which I can then use spyOn and spyOnProperty?

我还想知道 createSpyObj 定义中的属性数组的用途.到目前为止,我还没有在网上看到任何解释它的例子.

I would also like to know what the usage is of the properties array in the createSpyObj definition. So far I have not seen any example on the web that explains it.

推荐答案

根据 文档 (强调我的):

Per the documentation (emphasis mine):

您可以通过以下方式快速创建一个具有多个属性的间谍对象将属性数组或散列作为第三个参数传递给createSpyObj.在这种情况下,您将不会引用创建的间谍,所以如果你以后需要改变他们的间谍策略,你会必须使用 Object.getOwnPropertyDescriptor 方法.

You can create a spy object with several properties on it quickly by passing an array or hash of properties as a third argument to createSpyObj. In this case you won’t have a reference to the created spies, so if you need to change their spy strategies later, you will have to use the Object.getOwnPropertyDescriptor approach.

it("creates a spy object with properties", function() {
  let obj = createSpyObj("myObject", {}, { x: 3, y: 4 });
  expect(obj.x).toEqual(3);

  Object.getOwnPropertyDescriptor(obj, "x").get.and.returnValue(7);
  expect(obj.x).toEqual(7);
});

间谍属性是描述符(参见例如 Object.defineProperty on MDN),因此要访问间谍对象,您需要获取描述符对象,然后与 getset 方法定义就可以了.

Spied properties are descriptors (see e.g. Object.defineProperty on MDN), so to access the spy objects you need to get the descriptor object then interact with the get and set methods defined on it.

在 TypeScript 中,编译器需要一些帮助.createSpyObj 返回 anySpyObj,而 SpyObj 仅将 methods 定义为被监视上:

In TypeScript, the compiler needs a bit of help. createSpyObj returns either any or SpyObj<T>, and a SpyObj only defines the methods as being spied on:

type SpyObj<T> = T & {
    [K in keyof T]: T[K] extends Func ? T[K] & Spy<T[K]> : T[K];
               // |     if it's a     |    spy on it     | otherwise leave
               // |     callable      |                  | it alone
};

所以要在描述符的 getter 上访问 .and,您需要 可选链接(因为 Object.getOwnPropertyDescriptor 可能返回 undefined)和一个 类型断言到 Spy:

So to access .and on the descriptor's getter, you'll need optional chaining (as Object.getOwnPropertyDescriptor may return undefined) and a type assertion to a Spy:

(Object.getOwnPropertyDescriptor(obj, "x")?.get as Spy<() => number>).and.returnValue(7);

游乐场

这篇关于jasmine.createSpyObj 与属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

本站部分内容来源互联网,如果有图片或者内容侵犯了您的权益,请联系我们,我们会在确认后第一时间进行删除!

相关文档推荐

在开发JS过程中,会经常遇到两个小数相运算的情况,但是运算结果却与预期不同,调试一下发现计算结果竟然有那么长一串尾巴。如下图所示: 产生原因: JavaScript对小数运算会先转成二进制,运算完毕再转回十进制,过程中会有丢失,不过不是所有的小数间运算会
问题描述: 在javascript中引用js代码,然后导致反斜杠丢失,发现字符串中的所有\信息丢失。比如在js中引用input type=text onkeyup=value=value.replace(/[^\d]/g,) ,结果导致正则表达式中的\丢失。 问题原因: 该字符串含有\,javascript对字符串进行了转
Rails/Javascript: How to inject rails variables into (very) simple javascript(Rails/Javascript:如何将 rails 变量注入(非常)简单的 javascript)
CoffeeScript always returns in anonymous function(CoffeeScript 总是以匿名函数返回)
Ordinals in words javascript(javascript中的序数)
getFullYear returns year before on first day of year(getFullYear 在一年的第一天返回前一年)