Câu trả lời:
Vào tháng 2 năm 2017, họ đã hợp nhất một PR thêm tính năng này, họ đã phát hành vào tháng 4 năm 2017.
vì vậy để theo dõi getters / setters bạn sử dụng:
const spy = spyOnProperty(myObj, 'myGetterName', 'get');
trong đó myObj là phiên bản của bạn, 'myGetterName' là tên của đối tượng đó được định nghĩa trong lớp của bạn get myGetterName() {}
và tham số thứ ba là loại get
hoặc set
.
Bạn có thể sử dụng cùng các xác nhận mà bạn đã sử dụng với các gián điệp được tạo spyOn
.
Vì vậy, bạn có thể ví dụ:
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.
Đây là dòng trong mã nguồn github nơi có phương pháp này nếu bạn quan tâm.
Trả lời câu hỏi ban đầu, với jasmine 2.6.1, bạn sẽ:
const spy = spyOnProperty(myObj, 'valueA', 'get').andReturn(1);
expect(myObj.valueA).toBe(1);
expect(spy).toHaveBeenCalled();
Bất kỳ lý do gì bạn không thể chỉ thay đổi nó trên đối tượng trực tiếp? Nó không giống như thể javascript thực thi khả năng hiển thị của một thuộc tính trên một đối tượng.
spyOn
chỉ rõ ràng rằng tôi muốn chế nhạo một cái gì đó, trong khi tôi trực tiếp đặt thuộc tính ngầm chỉ ra rằng tôi muốn giả một cái gì đó và tôi không chắc ai đó sẽ hiểu rằng tôi đang chế nhạo một cái gì đó khi anh ta đang đọc mã. Trường hợp khác là tôi không muốn thay đổi hành vi bên trong của đối tượng, ví dụ nếu tôi thay đổi thuộc tính length cho một mảng, mảng được cắt, do đó, một mô hình sẽ tốt hơn
spyOn
.
spyOn
thất bại trong bài kiểm tra nếu tài sản không tồn tại.
TypeError: Cannot assign to read only property 'sessionStorage' of object '#<Window>'
Jasmine không có chức năng đó, nhưng bạn có thể hack một thứ gì đó cùng nhau bằng cách sử dụng Object.defineProperty
.
Bạn có thể cấu trúc lại mã của mình để sử dụng một hàm getter, sau đó theo dõi getter.
spyOn(myObj, 'getValueA').andReturn(1);
expect(myObj.getValueA()).toBe(1);
and.returnValue(1)
Cách tốt nhất là sử dụng spyOnProperty
. Nó yêu cầu 3 tham số và bạn cần chuyển get
hoặc set
như một tham số thứ ba.
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);
Ở đây tôi đang thiết lập get
của clientWidth
các div.nativeElement
đối tượng.
Nếu bạn đang sử dụng ES6 (Babel) hoặc TypeScript, bạn có thể khai báo thuộc tính bằng cách sử dụng trình truy cập get và set
export class SomeClassStub {
getValueA = jasmine.createSpy('getValueA');
setValueA = jasmine.createSpy('setValueA');
get valueA() { return this.getValueA(); }
set valueA(value) { this.setValueA(value); }
}
Sau đó, trong thử nghiệm của mình, bạn có thể kiểm tra xem thuộc tính có được đặt bằng:
stub.valueA = 'foo';
expect(stub.setValueA).toHaveBeenCalledWith('foo');
Cách thích hợp để làm điều này là với spy on property, nó sẽ cho phép bạn mô phỏng một thuộc tính trên một đối tượng với một giá trị cụ thể.
const spy = spyOnProperty(myObj, 'valueA').and.returnValue(1);
expect(myObj.valueA).toBe(1);
expect(spy).toHaveBeenCalled();
Giả sử có một phương pháp như thế này cần kiểm tra src
Thuộc tính của hình ảnh nhỏ cần kiểm tra
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 () bên dưới khiến "Hình ảnh mới" được cung cấp mã giả từ quá trình kiểm tra mã spyOn trả về một đối tượng chỉ có thuộc tính src
Vì biến "hook" có phạm vi hiển thị trong mã giả trong SpyOn và sau đó sau khi "reportABCEvent" được gọi
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');
});
Điều này dành cho jasmine 1.3 nhưng có thể hoạt động trên 2.0 nếu "andCallFake" được thay đổi thành tên 2.0
Tôi đang sử dụng lưới kiếm đạo và do đó không thể thay đổi cách triển khai thành phương pháp getter nhưng tôi muốn kiểm tra xung quanh điều này (mô phỏng lưới) chứ không phải kiểm tra chính lưới. Tôi đang sử dụng một đối tượng gián điệp nhưng điều này không hỗ trợ chế độ giả tài sản, vì vậy tôi thực hiện điều này:
this.$scope.ticketsGrid = {
showColumn: jasmine.createSpy('showColumn'),
hideColumn: jasmine.createSpy('hideColumn'),
select: jasmine.createSpy('select'),
dataItem: jasmine.createSpy('dataItem'),
_data: []
}
Nó hơi dài dòng nhưng nó hoạt động tốt
Tôi biết đến bữa tiệc ở đây hơi muộn nhưng,
Bạn có thể truy cập trực tiếp vào đối tượng cuộc gọi, đối tượng này có thể cung cấp cho bạn các biến cho mỗi cuộc gọi
expect(spy.calls.argsFor(0)[0].value).toBe(expectedValue)
valueA
là mộtObservable
hoặcSubject
? Tôi đang nhậnProperty valueA does not have access type get