인수를 기반으로 재스민 스파이를 수정하는 방법은 무엇입니까?


146

다른 매개 변수를 사용하여 외부 API 메서드를 두 번 호출하는 테스트하려는 함수가 있습니다. Jasmine 스파이 로이 외부 API를 조롱하고 매개 변수에 따라 다른 것을 반환하고 싶습니다. Jasmine에서 이것을 할 수있는 방법이 있습니까? 내가 생각해 낼 수있는 최선은 andCallFake를 사용하는 해킹입니다.

var functionToTest = function() {
  var userName = externalApi.get('abc');
  var userId = externalApi.get('123');
};


describe('my fn', function() {
  it('gets user name and ID', function() {
    spyOn(externalApi, 'get').andCallFake(function(myParam) {
      if (myParam == 'abc') {
        return 'Jane';
      } else if (myParam == '123') {
        return 98765;
      }
    });
  });
});

답변:


213

Jasmine 버전 3.0 이상에서는 withArgs

describe('my fn', function() {
  it('gets user name and ID', function() {
    spyOn(externalApi, 'get')
      .withArgs('abc').and.returnValue('Jane')
      .withArgs('123').and.returnValue(98765);
  });
});

3.0 이전의 Jasmine 버전 callFake은 올바른 방법이지만 객체를 사용하여 반환 값을 유지하여 단순화 할 수 있습니다

describe('my fn', function() {
  var params = {
    'abc': 'Jane', 
    '123': 98765
  }

  it('gets user name and ID', function() {
    spyOn(externalApi, 'get').and.callFake(function(myParam) {
     return params[myParam]
    });
  });
});

Jasmine 버전에 따라 구문이 약간 다릅니다.

  • 1.3.1 : .andCallFake(fn)
  • 2.0 : .and.callFake(fn)

자원:


11
이것은 지금 and.callFake- jasmine.github.io/2.2/... >
루시 베인

나는 다른 약속들을 돌려 주어야했기 때문에, 그 결과는 약간 다르게 보였다 : return q.when (params [myParam]) ;. 그렇지 않으면 이것은 내 문제에 대한 해결책이었습니다. 내 꿈의 해결책은 "and.returnValue"호출을 변경하는 것입니다.
빌 터너

7
재스민이 이것을 선언하는 더 좋은 방법이 있어야한다고 생각합니다. 좋아 spyOn(fake, 'method').withArgs('abc').and.returnValue('Jane')하고 spyOn(fake, 'method').withArgs('123').and.returnValue(98765).
jrharshath

@jrharshath는 .withArgs자스민 2.0에서 나를 위해 작동하지 않습니다
hemkaran_raghav

1
.withArgs실제로 사용할 수 없습니다-테스트를 ​​작성할 때 이러한 방법이 의미가 있음을 의미했습니다.
jrharshath

9

$provide스파이를 만드는 데 사용할 수도 있습니다 . 그리고 매개 변수가 지정된 데이터를 전달 하는 and.returnValues대신 사용하여 조롱하십시오 and.returnValue.

Jasmine 문서에 따르면 : 스파이를로 연결하면 and.returnValues함수에 대한 모든 호출은 반환 값 목록의 끝에 도달 할 때까지 특정 값을 순서대로 반환하며,이 시점에서 이후의 모든 호출에 대해 정의되지 않은 값이 반환됩니다.

describe('my fn', () => {
    beforeEach(module($provide => {
        $provide.value('externalApi', jasmine.createSpyObj('externalApi', ['get']));
    }));

        it('get userName and Id', inject((externalApi) => {
            // Given
            externalApi.get.and.returnValues('abc','123');

            // When
            //insert your condition

            // Then
            // insert the expectation                
        }));
});

테스트는 항상 스파이가 어떻게 호출되는지 정확히 알고 있어야하므로 returnValues여러 호출을 지원하기 위해 사용해야 합니다.
Schmuli

2
akhouri의 대답을 명확히하기 위해 :이 메소드 externalApi.get.and.returnValues('abc','123')it함수 내에서 호출 될 때만 작동 합니다. 그렇지 않으면 값 목록을 설정하면 테스트가 실행되는 순서를 예측할 수 없기 때문에 작동하지 않습니다. 실제로 테스트는 실행 순서에 의존해서는 안됩니다.
avi.elkharrat

0

필자의 경우 테스트 할 구성 요소가 있었고 생성자에는 다른 인수로 매번 두 번 호출되는 getAppConfigValue 라는 메소드가있는 구성 서비스가 있습니다 .

constructor(private configSvc: ConfigService) {
  this.configSvc.getAppConfigValue('a_string');
  this.configSvc.getAppConfigValue('another_string');
}

내 사양에서는 TestBed에서 다음과 같이 ConfigService를 제공했습니다.

{
  provide: ConfigService,
  useValue: {
    getAppConfigValue: (key: any): any {
      if (key === 'a_string) {
        return 'a_value';
      } else if (key === 'another_string') {
        return 'another_value';
      }
    }
  } as ConfigService
}

따라서 getAppConfigValue 의 서명 이 실제 ConfigService에 지정된 서명 과 동일하면 함수의 내부 기능을 수정할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.