[javascript] Jasmine으로 값 속성 (메서드가 아닌)을 감시하는 방법

Jasmine spyOn은 메서드의 동작을 변경하는 데 좋지만 객체의 값 속성 (메서드가 아닌)을 변경할 수있는 방법이 있습니까? 코드는 다음과 같을 수 있습니다.

spyOn(myObj, 'valueA').andReturn(1);
expect(myObj.valueA).toBe(1);



답변

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 소스 코드의 줄입니다.

https://github.com/jasmine/jasmine/blob/7f8f2b5e7a7af70d7f6b629331eb6fe0a7cb9279/src/core/requireInterface.js#L199

jasmine 2.6.1을 사용하여 원래 질문에 답하면 다음과 같이됩니다.

const spy = spyOnProperty(myObj, 'valueA', 'get').andReturn(1);
expect(myObj.valueA).toBe(1);
expect(spy).toHaveBeenCalled();


답변

개체에서 직접 변경할 수없는 이유는 무엇입니까? 자바 스크립트가 객체에 대한 속성의 가시성을 강제하는 것과는 다릅니다.


답변

Jasmine에는 이러한 기능이 없지만 .NET을 사용하여 함께 해킹 할 수 있습니다 Object.defineProperty.

getter 함수를 사용하도록 코드를 리팩터링 한 다음 getter를 감시 할 수 있습니다.

spyOn(myObj, 'getValueA').andReturn(1);
expect(myObj.getValueA()).toBe(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);

여기에 내가 설정하고 getclientWidthdiv.nativeElement객체를.


답변

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');


답변

이 작업을 수행하는 올바른 방법은 속성에 대한 스파이를 사용하는 것입니다. 그러면 특정 값을 가진 개체의 속성을 시뮬레이션 할 수 있습니다.

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 ()은 “new Image”에 테스트의 가짜 코드를 제공하도록합니다. 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에서 작동 할 수 있습니다.