Jasmine er det mest populære JS-bibliotek til unit testing-apps. I denne tutorial, designet til begyndere, præsenterer vi dig en hurtig og komplet guide til test med Jasmine.
Du bliver introduceret til Jasmine, en populær adfærdsdrevet testramme for JavaScript. Vi ser også et simpelt praktisk eksempel på, hvordan du skriver enhedstest med Jasmine, som kan hjælpe dig med let at kontrollere for fejl i din kode.
i nøddeskal ser vi, hvordan man skriver testsuiter, specifikationer og forventninger, og hvordan man anvender indbyggede Jasmine-matchere eller bygger dine egne tilpassede matchere
Vi ser også, hvordan du kan gruppere suiter for at organisere dine test for mere komplekse kodebaser.
Introduktion til Jasmine
Jasmine er en meget populær JavaScript-adfærdsdrevet udvikling (i BDD skriver du tests, før du skriver faktisk kode) rammer for enhedstest JavaScript-applikationer. Det giver værktøjer, der kan bruges til at køre automatiserede tests for både synkron og asynkron kode.
Jasmine har mange funktioner såsom:
- det er hurtigt og har lav overhead og ingen eksterne afhængigheder.
- det er et batteri inkluderet bibliotek og tilbyder alt hvad du behøver for at teste din kode.
- det er tilgængeligt både for Node og bro.ser.
- det kan bruges med andre sprog som Python og Ruby.
- det kræver ikke DOM.
- det giver en ren og let at forstå syntaks og også en rig og ligetil API.
- Vi kan bruge naturligt sprog til at beskrive testene og de forventede resultater.
Jasmine er et open source-værktøj, der er tilgængeligt under den tilladte MIT-licens. I skrivende stund er den seneste større version Jasmine 3.0, som giver nye funktioner og nogle brudændringer. 2.99-udgivelsen af Jasmine vil give forskellige afskrivningsadvarsler for suiter, der har forskellig adfærd i version 3.0, hvilket gør det nemt for udviklere at migrere til den nye version.
Du kan læse om de nye funktioner og bryde ændringer fra dette dokument.
brug af jasmin
Du kan bruge Jasmin på mange forskellige måder:
- på den gamle måde ved at inkludere både Jasmine core og dine testfiler ved hjælp af et
<scri
pt> tag, - som et CLI-værktøj ved hjælp af Node.js,
- som et bibliotek i Node.js,
- som en del af et build-system som Gulp.js eller Grunt.du kan også bruge Jasmine til at teste din Python-kode med jasmine-py, som kan installeres fra PyPI ved hjælp af kommandoen
pip install jasmine
. Denne pakke indeholder både en internetserver, der serverer og udfører en Jasmine suite til dit projekt, og et CLI-script til at køre test og kontinuerlige integrationer.Jasmine er også tilgængelig for Ruby projekter via jasmine-gem, som kan installeres ved at tilføje
gem 'jasmine'
til din Gemfile og kørerbundle install
. Det inkluderer en server til servering og kørsel af test, et CLI-script og også generatorer til Ruby on Rails-projekter.lad os nu fokusere på, hvordan du bruger Jasmine med JavaScript:
brug af Standalone Jasmine
Start med at hente den nyeste version af Jasmine fra udgivelsessiden.
udpak derefter simpelthen lynlåsfilen, helst inde i en mappe i det projekt, du vil teste.
mappen indeholder en masse standardfiler og mapper:
/src
: indeholder de kildefiler, du vil teste. Dette kan enten slettes, hvis du allerede har dit projekts mappeopsætning, eller kan også bruges, når det er relevant til hosting af din kildekode./lib
: indeholder kernen Jasmine filer./spec
: indeholder de tests, du skal skrive.SpecRunner.html
: denne fil bruges som testløber. Du kører dine specs ved blot at starte denne fil.Dette er indholdet af en standard
SpecRunner.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>
Husk at du skal ændre filerne inkluderet fra
/src
og/spec
mapper til at indeholde dine faktiske kilde-og testfiler.brug af Jasmine som Bibliotek
Du kan også bruge Jasmine som bibliotek i dit projekt. For eksempel importerer og udfører følgende kode Jasmine:
var Jasmine = require('jasmine');var jasmine = new Jasmine();jasmine.loadConfigFile('spec/support/jasmine.json');jasmine.execute();
først kræver vi/importerer Jasmine, og vi bruger
loadConfigFile()
metode til at indlæse konfigurationsfilen tilgængelig fraspec/support/jasmine.json
sti så endelig udfører vi Jasmine.brug af Jasmine via CLI
Du kan også bruge Jasmine fra CLI, som giver dig mulighed for nemt at køre Jasmine test og som standard output resultaterne i terminalen.
Vi følger denne tilgang for at køre vores eksempeltest i denne vejledning, så kør først følgende kommando for at installere Jasmine globalt:
npm install -g jasmine
du skal muligvis køre sudo til installation af npm-pakker globalt afhængigt af din npm-konfiguration.
Opret nu en mappe til dit projekt og naviger inde i det:
$ mkdir jasmine-project $ cd jasmine-project
kør derefter følgende kommando for at initialisere dit projekt til Jasmine:
denne kommando opretter simpelthen en spec-mappe og en JSON-konfigurationsfil. Dette er output fra
dir
kommando:.└── spec └── support └── jasmine.json2 directories, 1 file
Dette er indholdet af en standard
jasmine.json
fil:{ "spec_dir": "spec", "spec_files": pec.js" ], "helpers": , "stopSpecOnExpectationFailure": false, "random": true}
-
spec_dir
: angiver, hvor Jasmine søger efter testfiler. spec_files
: angiver mønstrene for testfiler, som standard alle JS-filer, der slutter med Spec-eller spec-strenge.-
helpers
: angiver, hvor Jasmine søger efter hjælperfiler. Hjælperfiler udføres før specifikationer og kan bruges til at definere brugerdefinerede matchere. -
stopSpecOnExpectationFailure
: når den er indstillet til true, stopper straks en spec på den første fejl i en forventning (kan bruges som en CLI-mulighed via--stop-on-failure
). -
random
: når den er indstillet til true Jasmine vil pseudo-tilfældigt køre test cases (kan bruges som en CLI mulighed via--random
).
spec_files
oghelpers
arrays kan også indeholde Glob-mønstre (takket være node-glob-pakken) til angivelse af filstier, som er mønstre, du normalt bruger til at specificere et sæt filer, når du arbejder i Bash (f. eks.ls *.js
).Hvis du ikke bruger standardplaceringen for
jasmine.json
konfigurationsfilen, skal du blot angive den brugerdefinerede placering viajasmine --config
valgmulighed.Du kan finde flere CLI-muligheder fra de officielle dokumenter.
forståelse Jasmine
i dette afsnit lærer vi om de grundlæggende elementer i Jasmine-test såsom suiter, SPECIFIKATIONER, forventninger, matchere og spioner osv.
i dit projekts mappe skal du køre følgende kommando for at initialisere et nyt Knudemodul:
Dette opretter en
package.json
fil med standardoplysninger:{ "name": "jasmine-project", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": , "author": "", "license": "ISC"}
Opret derefter en
index.js
fil og tilføj følgende kode: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};
suiter
en suite grupperer et sæt specs eller test cases. Det bruges til at teste en bestemt opførsel af JavaScript-koden, der normalt er indkapslet af et objekt/en klasse eller en funktion. Det er oprettet ved hjælp af Jasmine global-funktionen
describe()
, der tager to parametre, titlen på testsuiten og en funktion, der implementerer den faktiske kode for testsuiten.lad os starte med at oprette vores første test suite. Inde i
spec
mappe Opret enMyJSUtilitiesSpec.js
fil og tilføj:describe("MyJSUtilities", function() { /* ... */ });
MyJSUtilities er navnet på denne topniveau test suite.
sådan grupperes og Nest suiter
for bedre at organisere og præcist beskrive vores sæt tests kan vi nest suiter inde i top-level suite. Lad os f.eks. tilføje to suiter til MyJSUtilities-pakken:
describe("String Utils", function() { /*...*/});describe("Math Utils", function() { /*...*/});
inde i Math Utils-pakken, lad os også tilføje to indlejrede suiter:
describe("Basic Math Utils", function() { /* ... */ }); describe("Advanced Math Utils", function() { /* ... */ });
Vi grupperer relaterede tests i test for streng Utils, grundlæggende matematiske Utils og avancerede matematiske Utils og indlejrer dem inde i testen på topniveau suite myjsutilities. Dette vil komponere dine specs som træer svarende til en struktur af mapper.
indlejringsstrukturen vises på rapporten, hvilket gør det nemt for dig at finde mislykkede tests.
sådan udelukkes suiter
Du kan midlertidigt deaktivere en suite ved hjælp af funktionen
xdescribe()
. Den har samme signatur (parametre) som endescribe()
funktion, hvilket betyder, at du hurtigt kan deaktivere dine eksisterende suiter ved blot at tilføje enx
til funktionen.Specs inden for en
xdescribe()
funktion vil blive markeret afventende og ikke udført i rapporten.Specs
en spec erklærer en test sag, der tilhører en test suite. Dette gøres ved at kalde Jasmine global-funktionen
it()
, der tager to parametre, titlen på spec (som beskriver den logik, vi vil teste) og en funktion, der implementerer den faktiske testsag.en spec kan indeholde en eller flere forventninger. Hver forventning er simpelthen en påstand, der kan returnere enten
true
ellerfalse
. For at spec skal bestås, skal alle forventninger, der tilhører spec, væretrue
ellers fejler spec.inde i Vores streng Utils suite, tilføje disse specs:
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() { /*...*/ });});
inde i vores grundlæggende Math Utils suite lad os tilføje nogle specs:
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() { /*...*/ }); });
for de avancerede Math Utils, lad os tilføje specs:
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() { /*...*/ }); });
sådan udelukkes Specs
ligesom suiter kan du også ekskludere individuelle specs ved hjælp af
xit()
funktion, som midlertidigt deaktivererit()
spec og markerer spec som verserende.forventninger
forventninger oprettes ved hjælp af funktionen
expect()
, der tager en værdi kaldet den faktiske (dette kan være værdier, udtryk, variabler, funktioner eller objekter osv.). Forventninger komponerer spec og bruges sammen med matcher-funktioner (via kæde) til at definere, hvad udvikleren forventer af en bestemt kodeenhed at udføre.en matcher-funktion sammenligner mellem en faktisk værdi (overført til
expect()
– funktion, den er kædet med) og en forventet værdi (direkte overført som en parameter til matcheren) og returnerer enten sand eller falsk, som enten passerer eller fejler specifikationen.Du kan kæde
expect()
funktionen med flere matchere. For at negere / invertere det boolske resultat af enhver matcher kan du brugenot
søgeord, før du ringer til matcher.lad os implementere specifikationerne i vores eksempel. For nu bruger vi vi bruger
expect()
mednothing()
matcher, som er en del af de indbyggede matchere, som vi vil se lidt senere. Dette vil passere alle SPECIFIKATIONER, da vi ikke forventer noget på dette tidspunkt.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(); }); }); });});
Dette er et skærmbillede af resultaterne på dette tidspunkt:
Vi har otte bestået specifikationer og nul fejl.
Du kan enten bruge indbyggede matchere eller også oprette dine egne tilpassede matchere til dine specifikke behov.
indbyggede Matchere
Jasmine giver et rigt sæt indbyggede matchere. Lad os se nogle af de vigtige:
-
toBe()
til test for identitet, -
toBeNull()
til test fornull
, -
toBeUndefined()/toBeDefined()
for test forundefined
/notundefined
, -
toBeNaN()
til test for nan (ikke et tal) -
toEqual()
til test for lighed, -
toBeFalsy()/toBeTruthy()
til test for falskhed/sandfærdighed osv.
Du kan finde den fulde liste over matchere fra docs.
lad os nu implementere vores specifikationer med nogle af disse matchere, når det er relevant. Importer først de funktioner, vi tester i vores
MyJSUtilitiesSpec.js
fil:const utils = require("../index.js");
næste, start med strengen Utils suite og skift
expect().nothing()
med de relevante forventninger.for eksempel for den første spec forventer vi, at
toLowerCase()
– metoden først defineres og for det andet at returnere en lille bogstavstreng, dvs.:it("should be able to lower case a string",function() { expect(utils.toLowerCase).toBeDefined(); expect(utils.toLowerCase("HELLO WORLD")).toEqual("hello world"); });
Dette er den fulde kode for pakken:
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"); }); });
brugerdefinerede Matchere
Jasmine giver mulighed for at skrive brugerdefinerede matchere til implementering af påstande, der ikke er dækket af de indbyggede matchere eller bare for at gøre testene mere beskrivende og læsbare.
lad os for eksempel tage følgende 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(); });
lad os antage, at
isEven()
metoden er ikke implementeret. Hvis vi kører testene, får vi beskeder som følgende skærmbillede:fejlmeddelelsen, vi får, siger forventet udefineret at blive defineret, hvilket giver os ingen anelse om, hvad der sker. Så lad os gøre denne meddelelse mere meningsfuld i forbindelse med vores kodedomæne (dette vil være mere nyttigt for komplekse kodebaser). Lad os i denne sag oprette en brugerdefineret matcher.
Vi opretter tilpassede matchere ved hjælp af
addMatchers()
– metoden, der tager et objekt bestående af en eller mange egenskaber, der tilføjes som matchere. Hver ejendom skal give en fabriksfunktion, der tager to parametre:util
, som har et sæt hjælpefunktioner, som matchere kan bruge (se:matchersUtil.js
) ogcustomEqualityTesters
som skal sendes ind, hvisutil.equals
kaldes, og skal returnere et objekt med encompare
funktion, der vil blive kaldt for at kontrollere forventningen.vi skal registrere den brugerdefinerede matcher, før vi udfører hver spec ved hjælp af
beforeEach()
metode: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 derefter bruge den brugerdefinerede matcher i stedet for
expect(utils.isEven).toBeDefined()
:expect().hasEvenMethod();
Dette vil give os en bedre fejlmeddelelse:
brug beforeach() og aftereach()
til initialisering og rengøring af dine specifikationer giver Jasmine to globale funktioner,
beforeEach()
ogafterEach()
:beforeEach
funktionen kaldes en gang før hver spec i den Suite, hvor den kaldes.afterEach
funktionen kaldes en gang efter hver spec i den suite, hvor den hedder.
Hvis du for eksempel har brug for at bruge variabler i din testpakke, kan du blot erklære dem i starten af
describe()
– funktionen og sætte enhver initialiserings-eller instantiationskode inde i enbeforeEach()
– funktion. Endelig kan du brugeafterEach()
– funktionen til at nulstille variablerne efter hver spec, så du kan have ren enhedstest uden behov for at gentage initialisering og oprydningskode for hver spec.beforeEach()
– funktionen er også perfekt kombineret med mange Jasmine API ‘ er, såsomaddMatchers()
– metoden til at oprette brugerdefinerede matchere eller også meddone()
– funktionen for at vente på asynkrone operationer, før du fortsætter testen.manglende Test
Du kan tvinge en test til at mislykkes ved hjælp af den globale
fail()
metode tilgængelig i Jasmine. For eksempel:it("should explicitly fail", function () { fail('Forced to fail'); });
Du skal få følgende fejl:
test for undtagelser
når du er enhedstestning af din kode, kan fejl og undtagelser måske kastes, så du skal muligvis teste for disse scenarier. Jasmine giver
toThrow()
ogtoThrowError()
matchere til at teste for, hvornår en undtagelse kastes eller for at teste for en specifik undtagelse.for eksempel hvis vi har en funktion, der kaster en
TypeError
undtagelse:function throwsError() { throw new TypeError("A type error"); }
Du kan skrive en spec, der skal testes for, om en undtagelse kastes:
it('it should throw an exception', function () { expect(throwsError).toThrow(); });
eller du kan også bruge test for den specifikke
TypeError
undtagelse:it('it should throw a TypeError', function () { expect(throwsError).toThrowError(TypeError); });
forståelse af spioner
oftere end ikke afhænger metoder af andre metoder. Dette betyder, at når du tester en metode, kan du også ende med at teste dens afhængigheder. Dette anbefales ikke ved test, dvs.du skal sørge for at teste den rene funktion ved at isolere metoden og se, hvordan den opfører sig givet et sæt Input.Jasmine leverer spioner, der kan bruges til at spionere på/lytte til metodeopkald på objekter og rapportere, om en metode kaldes, og med hvilken kontekst og argumenter.
Jasmine giver to måder til spionage på metodeopkald: brug af
spyOn()
ellercreateSpy()
metoder.Du kan bruge
spyOn()
når metoden allerede findes på objektet, ellers skal du brugejasmine.createSpy()
som returnerer en ny funktion.som standard rapporterer en spion kun, hvis et opkald blev udført uden at ringe gennem funktionen spioneret (i.e funktionen stopper med at udføre), men du kan ændre standardadfærden ved hjælp af disse metoder:
-
and.callThrough()
: ring gennem den oprindelige funktion, -
and.returnValue(value)
: returner den angivne værdi, -
and.callFake(fn)
: den falske funktion i stedet for den oprindelige, -
and.throwError(err)
: kast en fejl, -
and.stub()
: nulstiller standard stubbing adfærd.
Du kan bruge en spion til at indsamle kørselsstatistikker om den spionerede funktion, for eksempel hvis du vil vide, hvor mange gange din funktion blev kaldt.
sig, at vi vil sikre os, at vores
toUpperCase()
metode gør brug af den indbyggedeString.toUpperCase()
metode, vi skal simpelthen spionere påString.toUpperCase()
ved hjælp af: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); });
testen er mislykket på grund af den anden forventning, fordi
utils.toUpperCase("hello world")
returnerede udefineret i stedet for den forventede hej verden. Det skyldes, som vi nævnte, tidligere efter at have oprettet spionen påtoUpperCase()
, metoden udføres ikke. Vi skal ændre denne standardadfærd ved at ringecallThrough()
:Bemærk venligst, at en
spy
funktion erstatter den spionerede funktion med en stub som standard. Hvis du skal ringe til den oprindelige funktion i stedet, kan du tilføje.and.callThrough()
til ditspy
objekt.var spytoUpperCase = spyOn(String.prototype, 'toUpperCase').and.callThrough();
nu passerer alle forventninger.
Du kan også bruge
and.callFake()
ellerand.returnValue()
til at falske enten den spionerede funktion eller bare returværdien, hvis du ikke ringer gennem den faktiske funktion:var spytoUpperCase = spyOn(String.prototype, 'toUpperCase').and.returnValue("HELLO WORLD");
var spytoUpperCase = spyOn(String.prototype, 'toUpperCase').and.callFake(function(){ return "HELLO WORLD"; });
nu, hvis vi ender med ikke at bruge den indbyggede
String.toUpperCase()
i vores egenutils.toUpperCase()
implementering, får vi disse fejl:de to forventninger
expect(String.prototype.toUpperCase).toHaveBeenCalled()
expect(spytoUpperCase.calls.count()).toEqual(1)
har fejlet.Sådan håndteres Asynkronicitet i Jasmine
Hvis den kode, du tester, indeholder asynkrone operationer, har du brug for en måde at fortælle Jasmine, når de asynkrone operationer er afsluttet.
Som standard venter Jasmine på, at enhver asynkron handling, defineret af et tilbagekald, løfte eller
async
søgeord, skal være færdig. Hvis Jasmine finder et tilbagekald, løfte eller async søgeord i en af disse funktioner:beforeEach
afterEach
beforeAll
afterAll
ogit
det venter på, at asynkronen skal udføres, før du fortsætter til næste operation.brug udført() med beforeEach()/it() ..
lad os tage vores eksempel
simulateAsyncOp()
som simulerer en asynkron operation ved hjælp afsetTimeout()
. I en virkelig verdensscenarie kan dette være en ajaks-anmodning eller noget lignende, der sker asynkront:function simulateAsyncOp(callback){
setTimeout(function () { callback(); }, 2000); }
for at teste denne funktion kan vi bruge
beforeEach()
funktion med den specielledone()
tilbagekald. Vores kode skal påberåbedone()
for at fortælle Jasmine, at den asynkrone operation er afsluttet: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 hurtigt bemærke en ulempe ved denne metode, så vi skal skrive vores kode for at acceptere
done()
tilbagekald. I vores tilfælde har vi ikke hardcodedone()
metode i voressimulateAsyncOp(fn)
men vi har givet en tilbagekaldsparameter bare for at kunne ringedone()
.brug af løfter
Hvis du ikke vil oprette kode, der afhænger af, hvordan du skriver din test, kan du i stedet bruge et løfte og ringe til
done()
tilbagekald, når løftet er løst. Eller endnu bedre, i Jasmine 2.7+, hvis din KODE Returnerer etPromise
, vil Jasmine vente, indtil det er løst eller afvist, før du udfører den næste kode.brug af async/afvent
Jasmine 2.7+ understøtter
async
ogawait
opkald i SPECIFIKATIONER. Dette fritager dig fra at sætte påstande i en.then()
eller.catch()
blok.it("should work with async/await", async () => { let completed = false; completed = await utils.simulateAsyncOp(); expect(completed).toEqual(true); });
Dette er implementeringen af
simulateAsyncOp
:function simulateAsyncOp() {
return new Promise(resolve => { setTimeout(() => { resolve(true); }, 1000); }); }
brug af Jasmine Clock
Jasmine clock bruges til at teste asynkron kode, der afhænger af tidsfunktioner som
setTimeout()
på samme måde tester vi synkron kode ved at spotte tidsbaserede API ‘ er med brugerdefinerede metoder. På denne måde kan du udføre de testede funktioner synkront ved at styre eller manuelt fremme uret.Du kan installere Jasmine-uret ved at kalde
jasmine.clock().install
– funktionen i din spec eller suite.når du har brugt uret, skal du afinstallere det for at gendanne de originale funktioner.
med Jasmine clock kan du styre JavaScript
setTimeout
ellersetInterval
funktioner ved at tjekke uret for at komme videre i tiden ved hjælp af funktionenjasmine.clock().tick
, som tager antallet af millisekunder, du kan flytte med.Du kan også bruge Jasmine-uret til at spotte den aktuelle dato.
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);});
Dette er
simulateAsyncOp
funktion:function simulateAsyncOp(callback){
setTimeout(function () { callback(); }, 1000); }
hvis du ikke angav et tidspunkt for
mockDate
funktionen, vil den bruge den aktuelle dato.håndtering af fejl
Hvis din asynkrone kode mislykkes på grund af en eller anden fejl, vil du have, at dine specifikationer mislykkes korrekt. Startende med Jasmine 2.6 + eventuelle uhåndterede fejl sendes til den aktuelt udførte spec.Jasmine giver også en måde, du kan bruge, hvis du har brug for eksplicit at fejle dine specifikationer:
- brug af
done()
tilbagekald medbeforeEach()
ved at kaldedone.fail(err)
metode, - blot at overføre en fejl til
done(err)
tilbagekald (Jasmine 3+), - kalder
reject()
metode til enPromise
.
konklusion
i denne vejledning har vi introduceret Jasmine og set, hvordan du kommer i gang med at bruge Jasmine til enhedstest af din JavaScript-kode. Tak fordi du læste!
denne artikel blev oprindeligt udgivet i techiediaries.
-