Jasmine的spyOn
可以改变方法的行为,但有没有办法改变对象的值属性(而不是方法)?代码可能如下所示:
spyOn(myObj, 'valueA').andReturn(1);
expect(myObj.valueA).toBe(1);
答案 0 :(得分:64)
2017年2月,他们合并了PR添加此功能,他们于2017年4月发布。
所以要监视你使用的getter / setter:
const spy = 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源代码中的行,如果您感兴趣,可以使用此方法。
使用jasmine 2.6.1回答原始问题,你会:
const spy = spyOnProperty(myObj, 'valueA', 'get').andReturn(1);
expect(myObj.valueA).toBe(1);
expect(spy).toHaveBeenCalled();
答案 1 :(得分:10)
Jasmine没有该功能,但您可以使用Object.defineProperty
一起破解某些内容。
您可以重构代码以使用getter函数,然后监视getter。
spyOn(myObj, 'getValueA').andReturn(1);
expect(myObj.getValueA()).toBe(1);
答案 2 :(得分:9)
您有什么理由不能直接在对象上更改它吗?这并不是说javascript强制对对象的属性进行可见性。
答案 3 :(得分:3)
如果您使用的是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');
答案 4 :(得分:3)
最好的方法是使用spyOnProperty
。它需要3个参数,您需要将get
或set
作为第三个参数传递。
const div = fixture.debugElement.query(By.css('.ellipsis-overflow'));
// now mock properties
spyOnProperty(div.nativeElement, 'clientWidth', 'get').and.returnValue(1400);
spyOnProperty(div.nativeElement, 'scrollWidth', 'get').and.returnValue(2400);
我在这里设置get
clientWidth
div.nativeElement
个import * as firebase from 'firebase/app';
import 'firebase/storage';
。{/ p>
答案 5 :(得分: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 2.0名称
答案 6 :(得分:1)
我正在使用kendo网格,因此无法将实现更改为getter方法,但我想测试一下(模拟网格)而不是测试网格本身。我使用的是间谍对象,但这不支持属性模拟,所以我这样做:
this.$scope.ticketsGrid = {
showColumn: jasmine.createSpy('showColumn'),
hideColumn: jasmine.createSpy('hideColumn'),
select: jasmine.createSpy('select'),
dataItem: jasmine.createSpy('dataItem'),
_data: []
}
它有点长啰嗦,但它有效吗
答案 7 :(得分:0)
我知道这里的派对有点晚了,但是,
您可以直接访问调用对象,它可以为您提供每次调用的变量
expect(spy.calls.argsFor(0)[0].value).toBe(expectedValue)
答案 8 :(得分:0)
正确的方法是对属性进行监视,它将使您可以模拟具有特定值的对象的属性。
const spy = spyOnProperty(myObj, 'valueA').and.returnValue(1);
expect(myObj.valueA).toBe(1);
expect(spy).toHaveBeenCalled();
答案 9 :(得分:-2)
你不能模拟变量,但你可以为它创建getter函数并在spec文件中模拟该方法。