Nesnesiz bir işlevi gözetlemek için Jasmine'i kullanma


154

Yasemin'de yeniyim ve kullanmaya başladım. Herhangi bir nesne (yani küresel) ile ilişkili olmayan işlevleri bir sürü kitaplık js dosyası var. Bu işlevlerde casusluk yapmaya nasıl devam edebilirim?

Nesne olarak pencere / belge kullanmayı denedim, ancak işlev çağrılmış olsa bile casus çalışmadı. Ayrıca aşağıdaki gibi sahte bir nesneye sarma denedim:

var fakeElement = {};
fakeElement.fakeMethod = myFunctionName;
spyOn(fakeElement, "fakeMethod");

ve ile test et

expect(fakeElement.fakeMethod).toHaveBeenCalled();

Casus çalışmadığı için bu da işe yaramıyor

Yanıtlar:


155

İşlevinizi tanımlıyorsanız:

function test() {};

Sonra, bu şuna eşittir:

window.test = function() {}  /* (in the browser) */

Yani spyOn(window, 'test') çalışmalıdır.

Değilse, şunları da yapabilmeniz gerekir:

test = jasmine.createSpy();

Bunların hiçbiri çalışmıyorsa, kurulumunuzda başka bir şey oluyor.

fakeElementPerde arkasında olup bitenlerden dolayı tekniğinizin işe yaradığını düşünmüyorum . Orijinal globalMethod hala aynı kodu gösterir. Casusluk ne yaparsa onu proxy yapar, ama sadece bir nesne bağlamında. Eğer test kodunuzu fakeElement aracılığıyla arayabilirseniz işe yarayacaktır, ancak o zaman global fns'den vazgeçebileceksiniz.


2
İşe yaradı! Daha önce yaptığım hata yöntem yerine spyOn yöntem () ile çağırıyordu olduğunu düşünüyorum. Teşekkürler!
Chetter Hummin

3
'Pencere' atanmamış olması nedeniyle testlerimizi otomasyonumuzun bir parçası olarak çalıştırmak için chutzpah kullanarak spyOn (window, 'test') kullanarak bazı sorunlar yaşadım. Jasmine.createSpy () kullanmak bu sorunu çözdü.
Henners

7
jasmine.createSpy () benim için mükemmel çalıştı. Teşekkürler!
dplass

1
kullanılan test = jasmine.createSpy();angularjs üzerinde casusluk $anchroScrollmükemmel çalıştı
Edgar Martinez

1
Herhangi bir nedenle çalışmak için her iki şekilde elde edemiyorum, ama mevcut bir pencere işlevini alay etmeye çalışıyorum çünkü tamamen mümkün olabilir; $window.open(url, '_blank');yeni bir sekme (veya tarayıcı kurulumuna bağlı olarak pencere) açmak amacıyla. Bu işlevi çağırdığından ve tarayıcıdan bağımsız olarak doğru url'ye gittiğini doğruladığımdan nasıl emin olmalıyım?
CSS

71

TypeScript kullanıcıları:

OP'nin javascript hakkında sorduğunu biliyorum, ancak içe aktarılan bir işlevi gözetlemek isteyen herhangi bir TypeScript kullanıcısı için şunları yapabilirsiniz.

Test dosyasında, işlevin içe aktarılmasını buradan dönüştürün:

import {foo} from '../foo_functions';

x = foo(y);

Buna:

import * as FooFunctions from '../foo_functions';

x = FooFunctions.foo(y);

Sonra casusluk yapabilirsiniz FooFunctions.foo:)

spyOn(FooFunctions, 'foo').and.callFake(...);
// ...
expect(FooFunctions.foo).toHaveBeenCalled();

3
TypeScript ipucu için teşekkürler. ES6 / Babel için aynı şekilde olmalı, ama denemedim.
hgoebl

1
Sadece işlev FooFunctions takma adı ile açıkça çağrılırsa çalışır gibi görünüyor . Baz () döndüren bir fabrika ve baz () foo () çağırıyor sınamak istiyorum bir işlev çubuğu () var. Bu yöntem bu senaryoda işe yaramıyor.
Richard Matsen

4
Bu takma ad foo_functions içine alınır export const FooFunctions = { bar, foo }; ve testte içe aktarma olur import { FooFunctions } from '../foo_functions'. Ancak çalışır, casusun çalışması için takma ad foo_functions özel uygulama içinde yine de açıkça kullanılması gerekir. const result = FooFunctions.foo(params)// casus raporları çağrı const result = foo(params)// casus raporları çağrı yok
Richard Matsen

2
Bir cazibe gibi çalıştı! Teşekkürler, bana çok zaman kazandın!
SrAxi

1
Bu artık çalışmıyorError: <spyOn> : parseCookie is not declared writable or has no setter
Ling Vu

42

Kullandığım 2 alternatif var (yasemin 2 için)

Bu çok açık değil çünkü fonksiyon aslında sahte.

test = createSpy().and.callFake(test); 

İkinci daha ayrıntılı, daha açık ve "daha temiz":

test = createSpy('testSpy', test).and.callThrough();

-> yasemin kaynak kodu ikinci argümanı görmek için


Bu biraz daha mantıklı ve başarı ile çoğaltmak için yeterince uzak. Benden +1. Teşekkürler, C§
CSS

9

Çok basit bir yol:

import * as myFunctionContainer from 'whatever-lib';

const fooSpy = spyOn(myFunctionContainer, 'myFunc');

1
import * as saveAsFunctions from 'file-saver';
..........
....... 
let saveAs;
            beforeEach(() => {
                saveAs = jasmine.createSpy('saveAs');
            })
            it('should generate the excel on sample request details page', () => {
                spyOn(saveAsFunctions, 'saveAs').and.callFake(saveAs);
                expect(saveAsFunctions.saveAs).toHaveBeenCalled();
            })

Bu benim için çalıştı.


4
Lütfen cevabınıza bir açıklama ekleyin, kod kendi başına ne olup bittiğini anlayamıyorlarsa soruyu soran kişi için yararlı değildir.
chevybow

0

Cevabım, içe aktarılan modülde tek (varsayılan dışa aktarma) işlevine sahip olduğum için @FlavorScape'e göre biraz farklı, aşağıdakileri yaptım:

import * as functionToTest from 'whatever-lib';

const fooSpy = spyOn(functionToTest, 'default');
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.