Jasmine är det mest populära JS-biblioteket för enhetstestning av webbappar. I denna handledning, designad för nybörjare, presenterar vi dig en snabb och komplett guide till testning med Jasmine.
Du kommer att introduceras till Jasmine, ett populärt beteendestyrt testramverk för JavaScript. Vi får också se ett enkelt praktiskt exempel på hur man skriver enhetstester med Jasmine som kan hjälpa dig att enkelt söka efter fel i din kod.
i nötskal ser vi hur man skriver testsviter, specifikationer och förväntningar och hur man applicerar inbyggda Jasmine matchers eller bygger egna matchers
Vi ser också hur du kan gruppera sviter för att organisera dina tester för mer komplexa kodbaser.
introduktion av Jasmine
Jasmine är en mycket populär JavaScript-beteendedriven utveckling (i BDD skriver du tester innan du skriver faktisk kod) ram för enhetstestning av JavaScript-applikationer. Det ger verktyg som kan användas för att köra automatiserade tester för både synkron och asynkron kod.
Jasmine har många funktioner som:
- Det är snabbt och har låg overhead och inga externa beroenden.
- Det är en batterier ingår bibliotek och erbjuder allt du behöver för att testa din kod.
- den är tillgänglig både för Node och webbläsaren.
- den kan användas med andra språk som Python och Ruby.
- Det kräver inte DOM.
- Det ger en ren och lätt att förstå syntax och även en rik och okomplicerad API.
- Vi kan använda naturligt språk för att beskriva testerna och de förväntade resultaten.
Jasmine är ett open source-verktyg som är tillgängligt under den tillåtna MIT-licensen. När detta skrivs är den senaste stora versionen Jasmine 3.0 som ger nya funktioner och några Brytande förändringar. 2.99-utgåvan av Jasmine kommer att ge olika avskrivningsvarningar för sviter som har olika beteende i version 3.0 vilket gör det enkelt för utvecklare att migrera till den nya versionen.
Du kan läsa om de nya funktionerna och bryta ändringar från det här dokumentet.
använda Jasmin
Du kan använda Jasmin på många olika sätt:
- på det gamla sättet genom att inkludera både Jasmine core och dina testfiler med en
<scri
pt> tagg, - som ett CLI-verktyg med nod.js,
- som ett bibliotek i Nod.js,
- som en del av ett byggsystem som Gulp.js eller Grunt.js via grunt-contrib-jasmine och gulp-jasmine-browser
Du kan också använda Jasmine för att testa din Python-kod med jasmine-py som kan installeras från PyPI med kommandot pip install jasmine
. Det här paketet innehåller både en webbserver som serverar och kör en Jasmine-svit för ditt projekt och ett CLI-skript för att köra tester och kontinuerliga integrationer.
Jasmine är också tillgängligt för Ruby-projekt via jasmine-gem som kan installeras genom att lägga till gem 'jasmine'
till din Gemfile och köra bundle install
. Den innehåller en server för servering och körning av tester, ett CLI-skript och även generatorer för Ruby on Rails-projekt.
låt oss nu fokusera på hur man använder Jasmine med JavaScript:
använda fristående Jasmine
börja med att ladda ner den senaste versionen av Jasmine från sidan releases.
extrahera sedan zip-filen, helst i en mapp i projektet du vill testa.
mappen innehåller en massa standardfiler och mappar:
/src
: innehåller källfilerna som du vill testa. Detta kan antingen raderas om du redan har projektets mappinställning eller kan också användas när det är lämpligt för att vara värd för din källkod.
/lib
: innehåller kärnan Jasmine filer.
/spec
: innehåller de tester som du ska skriva.
SpecRunner.html
: den här filen används som testlöpare. Du kör dina specifikationer genom att helt enkelt starta den här filen.
detta är innehållet i en standardSpecRunner.html
fil:
<!DOCTYPE html><html><head> <meta charset="utf-8"> <title>Jasmine Spec Runner v3.2.1</title> <link rel="shortcut icon" type="image/png" href="lib/jasmine-3.2.1/jasmine_favicon.png"> <link rel="stylesheet" href="lib/jasmine-3.2.1/jasmine.css"> <script src="lib/jasmine-3.2.1/jasmine.js"></script> <script src="lib/jasmine-3.2.1/jasmine-html.js"></script> <script src="lib/jasmine-3.2.1/boot.js"></script> <!-- include source files here... --> <script src="src/Player.js"></script> <script src="src/Song.js"></script> <!-- include spec files here... --> <script src="spec/SpecHelper.js"></script> <script src="spec/PlayerSpec.js"></script></head><body></body></html>
Kom ihåg att du måste ändra filerna som ingår i/src
och/spec
mappar för att innehålla dina faktiska käll-och testfiler.
använda Jasmine som Bibliotek
Du kan också använda Jasmine som bibliotek i ditt projekt. Till exempel importerar och kör följande kod Jasmine:
var Jasmine = require('jasmine');var jasmine = new Jasmine();jasmine.loadConfigFile('spec/support/jasmine.json');jasmine.execute();
först kräver vi/importerar Jasmine och vi använder loadConfigFile()
– metoden för att ladda konfigurationsfilen tillgänglig från spec/support/jasmine.json
sökväg så slutligen kör vi Jasmine.
använda Jasmine via CLI
Du kan också använda Jasmine från CLI som gör att du enkelt kan köra Jasmintest och som standard mata ut resultaten i terminalen.
vi följer detta tillvägagångssätt för att köra våra exempeltester i den här guiden, så först fortsätt och kör följande kommando för att installera Jasmine globalt:
npm install -g jasmine
du kan behöva köra sudo för att installera npm-paket globalt beroende på din npm-konfiguration.
Skapa nu en mapp för ditt projekt och navigera inuti det:
$ mkdir jasmine-project $ cd jasmine-project
kör sedan följande kommando för att initiera ditt projekt för Jasmine:
detta kommando skapar helt enkelt en spec-mapp och en JSON-konfigurationsfil. Detta är resultatet av dir
kommando:
.└── spec └── support └── jasmine.json2 directories, 1 file
detta är innehållet i en standard jasmine.json
fil:
{ "spec_dir": "spec", "spec_files": pec.js" ], "helpers": , "stopSpecOnExpectationFailure": false, "random": true}
-
spec_dir
: anger var Jasmine letar efter testfiler. -
spec_files
: anger mönster för testfiler, som standard alla JS-filer som slutar med Spec eller spec strängar. -
helpers
: anger var Jasmine letar efter hjälpfiler. Hjälparfiler körs före specifikationer och kan användas för att definiera anpassade matchare. -
stopSpecOnExpectationFailure
: när den är inställd på true kommer omedelbart att stoppa en spec på det första felet i en förväntan (kan användas som ett CLI-alternativ via--stop-on-failure
). -
random
: när den är inställd på true Jasmine kommer pseudo-slumpmässigt att köra testfallen (kan användas som ett CLI-alternativ via--random
).
spec_files
ochhelpers
matriser kan också innehålla Glob-mönster (tack vare node-glob-paketet) för att ange filvägar som är mönster som du vanligtvis använder för att ange en uppsättning filer när du arbetar i Bash (t.ex.ls *.js
).
om du inte använder standardplatsen förjasmine.json
konfigurationsfilen behöver du bara ange den anpassade platsen via alternativetjasmine --config
.
Du kan hitta fler CLI-alternativ från de officiella dokumenten.
förstå Jasmine
i det här avsnittet lär vi oss om de grundläggande elementen i Jasmintestning som sviter, SPECIFIKATIONER, förväntningar, matchare och spioner etc.
i projektets mapp Kör du följande kommando för att initiera en ny Nodmodul:
detta skapar en package.json
fil med standardinformation:
{ "name": "jasmine-project", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": , "author": "", "license": "ISC"}
skapa sedan en index.js
fil och Lägg till följande kod:
function fibonacci(n){ if (n === 1) { return ; } else { var s = fibonacci(n - 1); s.push(s + s); return s; }}function isPrime(num){ for (let i = 2; i < num; i++) if (num % i === 0) return false; return num !== 1 && num !== 0;}function isEven(n) { return n % 2 == 0;}function isOdd(n) { return Math.abs(n % 2) == 1;}function toLowerCase(str){ return str.toLowerCase();}function toUpperCase(str){ return str.toUpperCase();}function contains(str, substring, fromIndex){ return str.indexOf(substring, fromIndex) !== -1;}function repeat(str, n){ return (new Array(n + 1)).join(str);}module.exports = { fibonacci: fibonacci, isPrime: isPrime, isEven: isEven, isOdd: isOdd, toLowerCase: toLowerCase, toUpperCase: toUpperCase, contains: contains, repeat: repeat};
sviter
en svit grupperar en uppsättning specifikationer eller testfall. Det används för att testa ett specifikt beteende av JavaScript-koden som vanligtvis är inkapslad av ett objekt/klass eller en funktion. Det skapas med Jasmine global-funktionen describe()
som tar två parametrar, titeln på testsviten och en funktion som implementerar den faktiska koden för testsviten.
låt oss börja med att skapa vår första testpaket. Inutispec
mapp skapa enMyJSUtilitiesSpec.js
fil och Lägg till:
describe("MyJSUtilities", function() { /* ... */ });
MyJSUtilities är namnet på denna toppnivå testpaket.
hur man grupperar och Nest Suites
för bättre organisering och exakt beskrivning av vår uppsättning tester kan vi nest suites inne i toppnivåsviten. Låt oss till exempel lägga till två sviter i myjsutilities-sviten:
describe("String Utils", function() { /*...*/});describe("Math Utils", function() { /*...*/});
inuti Math Utils-sviten, låt oss också lägga till två kapslade sviter:
describe("Basic Math Utils", function() { /* ... */ }); describe("Advanced Math Utils", function() { /* ... */ });
vi grupperar relaterade tester i tester för sträng Utils, grundläggande matematiska Utils och avancerade matematiska Utils och häckar dem inuti toppnivåtestet suite myjsutilities. Detta kommer att komponera dina specifikationer som träd som liknar en struktur av mappar.
häckningsstrukturen visas i rapporten vilket gör det enkelt för dig att hitta misslyckade tester.
så här utesluter du sviter
Du kan tillfälligt inaktivera en svit med funktionenxdescribe()
. Den har samma signatur (parametrar) som en describe()
funktion vilket innebär att du snabbt kan inaktivera dina befintliga sviter genom att helt enkelt lägga till en x
till funktionen.
SPECIFIKATIONER inom ettxdescribe()
funktionen markeras i väntan och körs inte i rapporten.
SPECIFIKATIONER
en spec förklarar ett testfall som tillhör en testpaket. Detta görs genom att ringa Jasmine global-funktionen it()
som tar två parametrar, titeln på spec (som beskriver logiken vi vill testa) och en funktion som implementerar det faktiska testfallet.
en spec kan innehålla en eller flera förväntningar. Varje förväntan är helt enkelt ett påstående som kan returnera antingen true
eller false
. För att spec ska godkännas måste alla förväntningar som hör till spec vara true
annars misslyckas spec.
inuti vår sträng Utils suite, Lägg till dessa specifikationer:
describe("String Utils", function() { it("should be able to lower case a string",function() { /*...*/ }); it("should be able to upper case a string",function() { /*...*/ }); it("should be able to confirm if a string contains a substring",function() { /*...*/ }); it("should be able repeat a string multiple times",function() { /*...*/ });});
inuti vår Grundläggande Math Utils suite låt oss lägga till några specifikationer:
describe("Basic Math Utils", function() { it("should be able to tell if a number is even",function() { /*...*/ }); it("should be able to tell if a number is odd",function() { /*...*/ }); });
För de avancerade Math Utils, låt oss lägga till specifikationerna:
describe("Advanced Math Utils", function() { it("should be able to tell if a number is prime",function() { /*...*/ }); it("should be able to calculate the fibonacci of a number",function() { /*...*/ }); });
hur man utesluter SPECIFIKATIONER
precis som sviter kan du också utesluta enskilda specifikationer medxit()
funktion som tillfälligt inaktiverarit()
spec och markerar spec som väntande.
förväntningar
förväntningar skapas med funktionen expect()
som tar ett värde som kallas det faktiska (detta kan vara värden, uttryck, variabler, funktioner eller objekt etc.). Förväntningarna komponerar spec och används tillsammans med matcherfunktioner (via kedja) för att definiera vad utvecklaren förväntar sig av en specifik kodenhet att utföra.
en matcherfunktion jämför mellan ett verkligt värde (skickas till expect()
funktion som den är kedjad med) och ett förväntat värde (direkt passerat som en parameter till matcharen) och returnerar antingen sant eller falskt som antingen passerar eller misslyckas spec.
Du kan kedja funktionenexpect()
med flera matchare. För att negera / invertera det booleska resultatet av en matchare kan du använda nyckelordet not
innan du ringer matcharen.
låt oss implementera specifikationerna i vårt exempel. För tillfället använder vi we ’ll use expect()
med nothing()
matcher som är en del av de inbyggda matcharna som vi får se lite senare. Detta kommer att passera alla SPECIFIKATIONER eftersom vi inte förväntar oss något vid denna tidpunkt.
describe("MyJSUtilities", function() {describe(">String Utils", function() { it("should be able to lower case a string",function() { expect().nothing(); }); it("should be able to upper case a string",function() { expect().nothing(); }); it("should be able to confirm if a string contains a substring",function() { expect().nothing(); }); it("should be able repeat a string multiple times",function() { expect().nothing(); }); });describe("Math Utils", function() { describe("Basic Math Utils", function() { it("should be able to tell if a number is even",function() { expect().nothing(); }); it("should be able to tell if a number is odd",function() { expect().nothing(); }); }); describe("Advanced Math Utils", function() { it("should be able to tell if a number is prime",function() { expect().nothing(); }); it("should be able to calculate the fibonacci of a number",function() { expect().nothing(); }); }); });});
detta är en skärmdump av resultaten vid denna tidpunkt:
Vi har åtta godkända specifikationer och nollfel.
Du kan antingen använda inbyggda matchare eller också skapa egna anpassade matchare för dina specifika behov.
inbyggda matchare
Jasmine ger en rik uppsättning inbyggda matchare. Låt oss se några av de viktiga:
-
toBe()
för testning för identitet, -
toBeNull()
för testning förnull
, -
toBeUndefined()/toBeDefined()
för testning förundefined
/inteundefined
, -
toBeNaN()
för testning för Nan (inte ett nummer) -
toEqual()
för testning för jämlikhet, -
toBeFalsy()/toBeTruthy()
för testning för falskhet/sanningsenlighet etc.
Du kan hitta hela listan över matchare från docs.
Låt oss nu implementera våra specifikationer med några av dessa matchare när det är lämpligt. Importera först de funktioner vi testar i vårMyJSUtilitiesSpec.js
fil:
const utils = require("../index.js");
börja sedan med strängen Utils suite och ändraexpect().nothing()
med lämpliga förväntningar.
till exempel för den första specifikationen förväntar vi oss atttoLowerCase()
– metoden definieras först och för det andra att returnera en gemener, dvs:
it("should be able to lower case a string",function() { expect(utils.toLowerCase).toBeDefined(); expect(utils.toLowerCase("HELLO WORLD")).toEqual("hello world"); });
detta är den fullständiga koden för sviten:
describe(">String Utils", function() { it("should be able to lower case a string",function() { expect(utils.toLowerCase).toBeDefined(); expect(utils.toLowerCase("HELLO WORLD")).toEqual("hello world"); }); it("should be able to upper case a string",function() { expect(utils.toUpperCase).toBeDefined(); expect(utils.toUpperCase("hello world")).toEqual("HELLO WORLD"); }); it("should be able to confirm if a string contains a substring",function() { expect(utils.contains).toBeDefined(); expect(utils.contains("hello world","hello",0)).toBeTruthy(); }); it("should be able repeat a string multiple times",function() { expect(utils.repeat).toBeDefined(); expect(utils.repeat("hello", 3)).toEqual("hellohellohello"); }); });
anpassade matchare
Jasmine ger möjlighet att skriva anpassade matchare för att genomföra påståenden som inte omfattas av de inbyggda matcharna eller bara för att göra tester mer beskrivande och läsbara.
Låt oss till exempel ta följande spec:
it("should be able to tell if a number is even",function() { expect(utils.isEven).toBeDefined(); expect(utils.isEven(2)).toBeTruthy(); expect(utils.isEven(1)).toBeFalsy(); });
låt oss anta att isEven()
– metoden inte är implementerad. Om vi kör testerna får vi meddelanden som följande skärmdump:
felmeddelandet vi får säger förväntat odefinierat att definieras vilket ger oss ingen aning om vad som händer. Så låt oss göra detta meddelande mer meningsfullt i samband med vår koddomän (detta kommer att vara mer användbart för komplexa kodbaser). För denna fråga, låt oss skapa en anpassad matcher.
Vi skapar anpassade matchare medaddMatchers()
metod som tar ett objekt som består av en eller flera egenskaper som kommer att läggas till som matchare. Varje egenskap ska tillhandahålla en fabriksfunktion som tar två parametrar: util
, som har en uppsättning verktygsfunktioner för matchare att använda (se: matchersUtil.js
) och customEqualityTesters
som måste skickas in om util.equals
anropas och ska returnera ett objekt med en compare
funktion som kommer att anropas för att kontrollera förväntan.
Vi måste registrera den anpassade matcharen innan vi utför varje spec med beforeEach()
– metoden:
describe("/Basic Math Utils", function () {beforeEach(function () {jasmine.addMatchers({hasEvenMethod: function (util, customEqualityTesters) {return {compare: function (actual, expected) {var result = { pass: utils.isEven !== undefined };if (result.pass) {result.message = "Expected isEven() to be not defined."}else {result.message = "Expected isEven() to be defined."}return result;}}}});});/*...*/});
Vi kan sedan använda den anpassade matchen istället för expect(utils.isEven).toBeDefined()
:
expect().hasEvenMethod();
detta ger oss ett bättre felmeddelande:
använda beforeeach() och aftereach()
för att initiera och rengöra dina specifikationer ger Jasmine två globala funktioner, beforeEach()
och afterEach()
:
- funktionen
beforeEach
anropas en gång före varje spec i sviten där den kallas. - funktionen
afterEach
anropas en gång efter varje spec i sviten där den heter.
Om du till exempel behöver använda några variabler i din testpaket kan du helt enkelt deklarera dem i början av funktionen describe()
och lägga in någon initialiserings-eller instanseringskod i en beforeEach()
. Slutligen kan du använda funktionen afterEach()
för att återställa variablerna efter varje spec så att du kan ha ren enhetstestning utan att behöva upprepa initialisering och rengöringskod för varje spec.
beforeEach()
– funktionen kombineras också perfekt med många Jasmin-API: er som addMatchers()
– metoden för att skapa anpassade matchare eller också med done()
– funktionen för att vänta på asynkrona operationer innan du fortsätter testa.
misslyckas ett Test
Du kan tvinga ett test att misslyckas med den globalafail()
– metoden som finns i Jasmine. Till exempel:
it("should explicitly fail", function () { fail('Forced to fail'); });
Du bör få följande fel:
testning för undantag
När du enhetstestar din kod, fel och undantag kanske kastas, så du kan behöva testa för dessa scenarier. Jasmine gertoThrow()
ochtoThrowError()
matchare att testa för när ett undantag kastas eller att testa för ett specifikt undantag, respektive.
till exempel om vi har en funktion som kastar ettTypeError
undantag:
function throwsError() { throw new TypeError("A type error"); }
Du kan skriva en spec som ska testas för om ett undantag kastas:
it('it should throw an exception', function () { expect(throwsError).toThrow(); });
eller du kan också använda test för det specifika TypeError
undantag:
it('it should throw a TypeError', function () { expect(throwsError).toThrowError(TypeError); });
förstå spioner
oftare än inte, metoder beror på andra metoder. Det betyder att när du testar en metod kan du också sluta testa dess beroenden. Detta rekommenderas inte vid testning, dvs du måste se till att du testar den rena funktionen genom att isolera metoden och se hur den beter sig med tanke på en uppsättning ingångar.
Jasmine tillhandahåller spioner som kan användas för att spionera på/lyssna på metod uppmanar objekt och rapportera om en metod kallas och med vilket sammanhang och argument.
Jasmine ger två sätt att spionera på metodsamtal: använda spyOn()
eller createSpy()
metoder.
Du kan använda spyOn()
när metoden redan finns på objektet, annars måste du använda jasmine.createSpy()
som returnerar en ny funktion.
som standard rapporterar en spion endast om ett samtal gjordes utan att ringa via den spionerade funktionen (i.e funktionen slutar köra), men du kan ändra standardbeteendet med hjälp av dessa metoder:
-
and.callThrough()
: ring via den ursprungliga funktionen, -
and.returnValue(value)
: returnera det angivna värdet, -
and.callFake(fn)
: ring det angivna värdet, -
and.callFake(fn)
falsk funktion istället för den ursprungliga, -
and.throwError(err)
: kasta ett fel, -
and.stub()
: återställer standardstubbningsbeteendet.
Du kan använda en spion för att samla run-time statistik om spionerade funktionen, till exempel om du vill veta hur många gånger din funktion kallades.
säg att vi vill se till att vår toUpperCase()
metod använder den inbyggda String.toUpperCase()
metod, vi måste helt enkelt spionera på String.toUpperCase()
med:
it("should be able to upper case a string", function () {
var spytoUpperCase = spyOn(String.prototype, 'toUpperCase')
expect(utils.toUpperCase).toBeDefined(); expect(utils.toUpperCase("hello world")).toEqual("HELLO WORLD"); expect(String.prototype.toUpperCase).toHaveBeenCalled(); expect(spytoUpperCase.calls.count()).toEqual(1); });
testet har misslyckats på grund av den andra förväntan eftersom utils.toUpperCase("hello world")
återvände odefinierad istället för den förväntade Hello World. Det beror på att, som vi nämnde, tidigare efter att ha skapat spion på toUpperCase()
, utförs metoden inte. Vi måste ändra detta standardbeteende genom att ringa callThrough()
:
Observera att en
spy
– funktion ersätter den spionerade funktionen med en stub som standard. Om du behöver ringa den ursprungliga funktionen istället kan du lägga till.and.callThrough()
till dittspy
objekt.
var spytoUpperCase = spyOn(String.prototype, 'toUpperCase').and.callThrough();
nu passerar alla förväntningar.
Du kan också använda and.callFake()
eller and.returnValue()
för att förfalska antingen den spionerade funktionen eller bara returvärdet om du inte ringer igenom den faktiska funktionen:
var spytoUpperCase = spyOn(String.prototype, 'toUpperCase').and.returnValue("HELLO WORLD");
var spytoUpperCase = spyOn(String.prototype, 'toUpperCase').and.callFake(function(){ return "HELLO WORLD"; });
Nu, om vi slutar inte använda den inbyggda String.toUpperCase()
I vår egen utils.toUpperCase()
implementering, får vi dessa fel:
de två förväntningarna expect(String.prototype.toUpperCase).toHaveBeenCalled()
expect(spytoUpperCase.calls.count()).toEqual(1)
har misslyckats.
hur man hanterar Asynkronicitet i Jasmine
Om koden du testar innehåller asynkrona operationer behöver du ett sätt att låta Jasmine veta när de asynkrona operationerna har slutförts.
som standard väntar Jasmine på att någon asynkron operation, definierad av en återuppringning, löfte eller async
nyckelord, ska slutföras. Om Jasmine hittar ett callback, promise eller async-nyckelord i en av dessa funktioner: beforeEach
afterEach
beforeAll
afterAll
och it
det väntar på att det asynkrona ska göras innan du fortsätter till nästa operation.
använda klar () med beforeEach ()/it ()..
Låt oss ta vårt exempel simulateAsyncOp()
som simulerar en asynkron operation med setTimeout()
. I ett verkligt världsscenario kan detta vara en Ajax-begäran eller något liknande som händer asynkront:
function simulateAsyncOp(callback){
setTimeout(function () { callback(); }, 2000); }
för att testa denna funktion kan vi använda funktionen beforeEach()
med specialfunktionen done()
återuppringning. Vår kod måste åberopadone()
för att berätta för Jasmine att den asynkrona operationen har slutförts:
describe("/Async Op", function () {var asyncOpCompleted = false;beforeEach(function (done) {utils.simulateAsyncOp(function(){ asyncOpCompleted = true; done();});});it("should be able to tell if the async call has completed", function () { expect(asyncOpCompleted).toEqual(true);});});
Vi kan snabbt märka en nackdel med denna metod, så vi måste skriva vår kod för att acceptera done()
återuppringning. I vårt fall har vi inte hårdkodatdone()
– metoden i vårsimulateAsyncOp(fn)
men vi har tillhandahållit en återuppringningsparameter bara för att kunna ringadone()
.
använda löften
Om du inte vill skapa kod som beror på hur du skriver ditt test kan du istället använda ett löfte och ringa done()
återuppringning när löftet har lösts. Eller ännu bättre, i Jasmine 2.7+, om din KOD Returnerar ett Promise
, väntar Jasmine tills det är löst eller avvisat innan nästa kod körs.
använda async/väntar
Jasmine 2.7+ stöderasync
ochawait
samtal i SPECIFIKATIONER. Detta befriar dig från att sätta påståenden i ett .then()
eller .catch()
block.
it("should work with async/await", async () => { let completed = false; completed = await utils.simulateAsyncOp(); expect(completed).toEqual(true); });
detta är implementeringen av simulateAsyncOp
:
function simulateAsyncOp() {
return new Promise(resolve => { setTimeout(() => { resolve(true); }, 1000); }); }
använda Jasminklocka
Jasminklockan används för att testa asynkron kod som beror på tidsfunktioner somsetTimeout()
på samma sätt testar vi synkron kod genom att spotta tidsbaserade API: er med anpassade metoder. På detta sätt kan du utföra de testade funktionerna synkront genom att styra eller manuellt flytta klockan.
Du kan installera Jasminklockan genom att ringa funktionen jasmine.clock().install
I DIN spec eller suite.
När du har använt klockan måste du avinstallera den för att återställa de ursprungliga funktionerna.
med Jasmine clock kan du styra JavaScriptsetTimeout
ellersetInterval
funktioner genom att markera klockan för att avancera i tid med funktionenjasmine.clock().tick
, som tar antalet millisekunder du kan flytta med.
Du kan också använda Jasminklockan för att håna det aktuella datumet.
beforeEach(function () {jasmine.clock().install();});afterEach(function() {jasmine.clock().uninstall();});it("should call the asynchronous operation synchronously", function() {var completed = false;utils.simulateAsyncOp(function(){completed = true;});expect(completed).toEqual(false);jasmine.clock().tick(1001);expect(completed).toEqual(true);});
detta är funktionen simulateAsyncOp
:
function simulateAsyncOp(callback){
setTimeout(function () { callback(); }, 1000); }
om du inte angav en tid för funktionen
mockDate
används det aktuella datumet.
hanteringsfel
om din asynkrona kod misslyckas på grund av något fel, vill du att dina specifikationer misslyckas korrekt. Från och med Jasmine 2.6 + skickas eventuella ohanterade fel till den för närvarande utförda spec.
Jasmine ger också ett sätt du kan använda om du behöver uttryckligen misslyckas med dina specifikationer:
- använda
done()
återuppringning medbeforeEach()
genom att ringadone.fail(err)
metod, - skickar helt enkelt ett fel till
done(err)
återuppringning (Jasmine 3+), - ringa
reject()
metod för enPromise
.
slutsats
i den här guiden har vi introducerat Jasmine och sett hur du kommer igång med Jasmine för att testa din JavaScript-kod. Tack för att du läste!
den här artikeln publicerades ursprungligen i techiediaries.