Javascript 如何使用Jasmine监视值属性(而不是方法)
Jasmine的Javascript 如何使用Jasmine监视值属性(而不是方法),javascript,unit-testing,mocking,jasmine,Javascript,Unit Testing,Mocking,Jasmine,Jasmine的spyOn可以很好地更改方法的行为,但是有没有办法更改对象的值属性(而不是方法)?代码可能如下所示: spyOn(myObj, 'valueA').andReturn(1); expect(myObj.valueA).toBe(1); 有什么原因不能直接在对象上更改它吗?这并不是说javascript在对象上强制属性的可见性。Jasmine没有该功能,但您可以使用对象.defineProperty将某些内容组合在一起 您可以重构代码以使用getter函数,然后监视getter
spyOn
可以很好地更改方法的行为,但是有没有办法更改对象的值属性(而不是方法)?代码可能如下所示:
spyOn(myObj, 'valueA').andReturn(1);
expect(myObj.valueA).toBe(1);
有什么原因不能直接在对象上更改它吗?这并不是说javascript在对象上强制属性的可见性。Jasmine没有该功能,但您可以使用
对象.defineProperty
将某些内容组合在一起
您可以重构代码以使用getter函数,然后监视getter
spyOn(myObj, 'getValueA').andReturn(1);
expect(myObj.getValueA()).toBe(1);
假设有这样一种方法需要测试 需要检查微小图像的
src
属性
function reportABCEvent(cat, type, val) {
var i1 = new Image(1, 1);
var link = getABC('creosote');
link += "&category=" + String(cat);
link += "&event_type=" + String(type);
link += "&event_value=" + String(val);
i1.src = link;
}
下面的spyOn()导致“新图像”接收来自测试的伪代码
spyOn代码返回一个只有src属性的对象
因为变量“hook”的作用域是在SpyOn中的伪代码中可见的,并且在调用“reportABCEvent”之后也是可见的
describe("Alphabetic.ads", function() {
it("ABC events create an image request", function() {
var hook={};
spyOn(window, 'Image').andCallFake( function(x,y) {
hook={ src: {} }
return hook;
}
);
reportABCEvent('testa', 'testb', 'testc');
expect(hook.src).
toEqual('[zubzub]&arg1=testa&arg2=testb&event_value=testc');
});
这是针对jasmine 1.3的,但如果“andCallFake”改为
2.0名称我使用的是剑道网格,因此无法将实现更改为getter方法,但我希望围绕这一点进行测试(模拟网格),而不是测试网格本身。我使用的是间谍对象,但它不支持属性模拟,所以我这样做:
this.$scope.ticketsGrid = {
showColumn: jasmine.createSpy('showColumn'),
hideColumn: jasmine.createSpy('hideColumn'),
select: jasmine.createSpy('select'),
dataItem: jasmine.createSpy('dataItem'),
_data: []
}
有点啰嗦,但很管用我来这里参加聚会有点晚了,我知道,但是 您可以直接访问calls对象,它可以为您提供每个调用的变量
expect(spy.calls.argsFor(0)[0].value).toBe(expectedValue)
如果您使用的是ES6(Babel)或TypeScript,那么可以使用get和set访问器来清除属性
export class SomeClassStub {
getValueA = jasmine.createSpy('getValueA');
setValueA = jasmine.createSpy('setValueA');
get valueA() { return this.getValueA(); }
set valueA(value) { this.setValueA(value); }
}
然后在测试中,您可以检查属性是否设置为:
stub.valueA = 'foo';
expect(stub.setValueA).toHaveBeenCalledWith('foo');
2017年2月,他们合并了一家公关公司,并在2017年4月发布了这一功能 因此,要监视您使用的getter/setter:
constspy=spyOnProperty(myObj,'myGetterName','get')代码>
其中myObj是您的实例,“myGetterName”是在类中定义为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源代码中的一行,如果您感兴趣,可以使用此方法
而spyOnProperty方法是
用jasmine 2.6.1回答最初的问题,你会:
const spy = spyOnProperty(myObj, 'valueA', 'get').andReturn(1);
expect(myObj.valueA).toBe(1);
expect(spy).toHaveBeenCalled();
最好的方法是使用spyOnProperty
。它需要3个参数,您需要将get
或set
作为第三个参数传递
例子
这里我设置了div.nativeElement
对象的clientWidth
的get
。您不能模拟变量,但可以为它创建getter函数,并在spec文件中模拟该方法。正确的方法是使用spy on属性,它将允许您在具有特定值的对象上模拟特性
const spy = spyOnProperty(myObj, 'valueA').and.returnValue(1);
expect(myObj.valueA).toBe(1);
expect(spy).toHaveBeenCalled();
使用spyOn
显式地表示我想要模拟某物,而我直接设置属性隐式地表示我想要模拟某物,我不确定其他人在阅读代码时是否会理解我在模拟某物。另一种情况是,我不想更改对象的内部行为,例如,如果我更改数组的length属性,则会修剪数组,因此将创建一个模拟better@Shuping,在这种情况下,你不会嘲笑。你会打短棍的,这很好。您将仅在测试内部“更改行为”,这是您试图使用spyOn
实现的。您可能希望监视运行时对象原型,以确保该属性在运行时存在。JasminespyOn
如果属性不存在,则测试失败。一个示例是设置或删除window.sessionStorage:TypeError:无法分配给对象“#”的只读属性“sessionStorage”
在javascriptYes中并不总是可以重新分配对象属性,这就是我现在能做的。对于jasmine 2,它是:和.returnValue(1)
如果valueA
是一个可观察的或主题
,我该怎么做?我正在获取属性值a没有访问类型get
,这可能意味着您无法在该属性上使用它。spyOnProperty正在使用getOwnPropertyDescriptor并检查该属性描述符的访问类型get | set是否存在。您得到的错误是因为没有为您试图监视的属性设置或获取属性描述符。Jasmine会这样做:const descriptor=Object.getOwnPropertyDescriptor。。。如果(!descriptor[accessType]){//error被抛出}那么,如果没有显式的getter和setter方法,就无法监视属性?间谍是一种被使用的财产。@Dominik这里我在一篇较长的文章中写了所有与此相关的秘密内容:@Mathieu这不是一个好的断言,因为它只是断言了我们从我们告诉间谍所做的事情中已经知道的东西,但这正是他们所问的和他们的问题代码片段。”_(ツ)_/'他们问题的重点是如何监视属性,而不是他们的具体示例。或者,如果getter是被测试类的一部分,则可以将存根注入子类中。
const spy = spyOnProperty(myObj, 'valueA').and.returnValue(1);
expect(myObj.valueA).toBe(1);
expect(spy).toHaveBeenCalled();