จัสมินspyOnเป็นสิ่งที่ดีในการเปลี่ยนพฤติกรรมของวิธีการ แต่มีวิธีใดในการเปลี่ยนคุณสมบัติค่า (แทนที่จะเป็นวิธีการ) สำหรับวัตถุหรือไม่? รหัสอาจเป็นดังนี้:
spyOn(myObj, 'valueA').andReturn(1);
expect(myObj.valueA).toBe(1);
          จัสมินspyOnเป็นสิ่งที่ดีในการเปลี่ยนพฤติกรรมของวิธีการ แต่มีวิธีใดในการเปลี่ยนคุณสมบัติค่า (แทนที่จะเป็นวิธีการ) สำหรับวัตถุหรือไม่? รหัสอาจเป็นดังนี้:
spyOn(myObj, 'valueA').andReturn(1);
expect(myObj.valueA).toBe(1);
          คำตอบ:
ในเดือนกุมภาพันธ์ 2017 พวกเขาได้รวมการประชาสัมพันธ์เพื่อเพิ่มคุณสมบัตินี้ซึ่งเปิดตัวในเดือนเมษายน 2017
เพื่อสอดแนม getters / setters ที่คุณใช้:
 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 ที่มีวิธีนี้หากคุณสนใจ
ตอบคำถามเดิมด้วยดอกมะลิ 2.6.1 คุณจะ:
const spy = spyOnProperty(myObj, 'valueA', 'get').andReturn(1);
expect(myObj.valueA).toBe(1);
expect(spy).toHaveBeenCalled();
              เหตุผลใดที่คุณไม่สามารถเปลี่ยนมันบนวัตถุได้โดยตรง? ไม่เหมือนกับว่าจาวาสคริปต์บังคับให้มองเห็นคุณสมบัติบนวัตถุ
spyOnบ่งบอกอย่างชัดเจนว่าฉันต้องการเยาะเย้ยอะไรบางอย่างในขณะที่ฉันตั้งค่าคุณสมบัติโดยตรงโดยปริยายบ่งบอกว่าฉันต้องการล้อเลียนอะไรบางอย่างและฉันไม่แน่ใจว่าคนอื่นจะเข้าใจว่าฉันกำลังล้อเลียนบางสิ่งบางอย่างเมื่อเขากำลังอ่านรหัส อีกกรณีคือฉันไม่ต้องการเปลี่ยนพฤติกรรมภายในของวัตถุเช่นถ้าฉันเปลี่ยนคุณสมบัติความยาวของอาร์เรย์อาร์เรย์จะถูกตัดออกดังนั้นการจำลองจะดีกว่า
                    spyOn.
                    spyOnไม่ผ่านการทดสอบหากคุณสมบัติไม่มีอยู่จริง
                    TypeError: Cannot assign to read only property 'sessionStorage' of object '#<Window>'
                    จัสมินไม่มีฟังก์ชั่นนั้น แต่คุณอาจแฮ็คบางอย่างร่วมกันได้โดยใช้ Object.definePropertyแต่คุณอาจจะสามารถที่จะตัดบางสิ่งบางอย่างร่วมกันโดยใช้
คุณสามารถ refactor โค้ดของคุณเพื่อใช้ฟังก์ชัน getter จากนั้นสอดแนมที่ getter
spyOn(myObj, 'getValueA').andReturn(1);
expect(myObj.getValueA()).toBe(1);
              and.returnValue(1)
                    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วัตถุ
หากคุณใช้ ES6 (Babel) หรือ TypeScript คุณสามารถดึงคุณสมบัติออกโดยใช้ get และ set accessors
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');
              วิธีที่ถูกต้องในการทำเช่นนี้คือการสอดแนมทรัพย์สินซึ่งจะช่วยให้คุณสามารถจำลองคุณสมบัติบนวัตถุที่มีค่าเฉพาะได้
const spy = spyOnProperty(myObj, 'valueA').and.returnValue(1);
expect(myObj.valueA).toBe(1);
expect(spy).toHaveBeenCalled();
              สมมติว่ามีวิธีการเช่นนี้ที่ต้องทดสอบ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 แต่อาจใช้ได้กับ 2.0 ถ้า "andCallFake" ถูกเปลี่ยนเป็นชื่อ 2.0
ฉันใช้กริดเคนโดดังนั้นจึงไม่สามารถเปลี่ยนการใช้งานเป็นวิธี getter ได้ แต่ฉันต้องการทดสอบสิ่งนี้ (เยาะเย้ยกริด) และไม่ได้ทดสอบกริดเอง ฉันใช้วัตถุสอดแนม แต่สิ่งนี้ไม่สนับสนุนการล้อเลียนทรัพย์สินดังนั้นฉันจึงทำสิ่งนี้:
    this.$scope.ticketsGrid = { 
        showColumn: jasmine.createSpy('showColumn'),
        hideColumn: jasmine.createSpy('hideColumn'),
        select: jasmine.createSpy('select'),
        dataItem: jasmine.createSpy('dataItem'),
        _data: []
    } 
ค่อนข้างยืดเยื้อ แต่ใช้ได้ผลดี
ฉันไปงานปาร์ตี้ที่นี่ช้าไปหน่อย แต่ฉันรู้ว่า
คุณสามารถเข้าถึงวัตถุการโทรได้โดยตรงซึ่งสามารถให้ตัวแปรสำหรับการโทรแต่ละครั้ง
expect(spy.calls.argsFor(0)[0].value).toBe(expectedValue)
              คุณไม่สามารถเยาะเย้ยตัวแปรได้ แต่คุณสามารถสร้างฟังก์ชัน getter และจำลองวิธีการนั้นในไฟล์ข้อมูลจำเพาะของคุณได้
valueAเป็นObservableหรือSubject? กำลังเดินทางProperty valueA does not have access type get