Yasemin casuslarını argümanlara göre değiştirmenin bir yolu var mı?


147

Farklı parametreler kullanarak, harici bir API yöntemini iki kez çağıran test etmek istediğiniz bir fonksiyonum var. Bu harici API'yi bir Yasemin casusuyla alay etmek ve parametrelere göre farklı şeyler döndürmek istiyorum. Yasemin'de bunu yapmanın bir yolu var mı? Ben gelebilir en iyi andCallFake kullanarak bir kesmek:

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

Yanıtlar:


215

Jasmine 3.0 ve sonraki sürümlerde şunları kullanabilirsiniz: 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);
  });
});

Jasmine'in 3.0'dan önceki sürümleri callFakeiçin doğru yol budur, ancak dönüş değerlerini tutmak için bir nesne kullanarak basitleştirebilirsiniz.

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'in sürümüne bağlı olarak, sözdizimi biraz farklıdır:

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

Kaynaklar:


11
Bu şimdi and.callFake- jasmine.github.io/2.2/… >
Lucy Bain

Ben farklı vaatler dönmek zorunda kaldı, bu yüzden dönüş biraz farklı görünüyordu: dönüş q.when (params [myParam]) ;. Aksi takdirde, bu benim sorunum için bir çözüm oldu. Rüya çözümüm "ve.returnValue" çağrılarını değiştirmek olacaktır.
Bill Turner

7
yasemin bunu ilan etmenin daha iyi bir yoluna sahip olmalı. Gibi spyOn(fake, 'method').withArgs('abc').and.returnValue('Jane')ve spyOn(fake, 'method').withArgs('123').and.returnValue(98765).
jrharshath

@jrharshath .withArgsyasemin 2.0 benim için çalışmıyor
hemkaran_raghav

1
.withArgsgerçekten mevcut değil - böyle bir yöntemin testler yazarken mantıklı olacağı anlamına geliyordu.
jrharshath

9

$provideBir casus oluşturmak için de kullanabilirsiniz . Ve parametreli verileri aktarmak and.returnValuesyerine kullanarak alay et and.returnValue.

Yasemin belgelerine göre: Casus ile zincirleme and.returnValuesyaparak, işleve yapılan tüm çağrılar, dönüş değerleri listesinin sonuna ulaşıncaya kadar belirli değerleri döndürür; bu noktada sonraki tüm çağrılar için tanımsız olarak geri döner.

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

Bu doğru cevaptır, çünkü bir test her zaman bir casusun nasıl çağrılacağını tam olarak bilmeli ve bu nedenle sadece returnValuesbirden fazla çağrıyı desteklemek için kullanmalıdır
Schmuli

2
Sadece akhouri'nin cevabını açıklığa kavuşturmak için: bu yöntem sadece fonksiyon externalApi.get.and.returnValues('abc','123')içinde çağrıldığında itçalışır. Aksi takdirde, değerlerin bir listesini ayarlarsanız, başka bir yerde, hiçbir zaman çalışmaz, çünkü testlerin yürütüldüğü sıra tahmin edilemez. Aslında testler, uygulandıkları sıraya bağlı olmamalıdır.
avi.elkharrat

0

Benim durumumda, test ettiğim bir bileşenim vardı ve yapıcısında , her seferinde farklı argümanlarla iki kez çağrılan getAppConfigValue adlı bir yöntemle bir yapılandırma hizmeti var :

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

Benim spesifikasyonumda, TestBed'deki ConfigService'i şu şekilde sağladım:

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

Bu nedenle, getAppConfigValue imzası , gerçek ConfigService'te belirtilenle aynı olduğu sürece, işlevin dahili olarak yapabilecekleri değiştirilebilir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.