Hyperledger Fabric Tutorial: Omfattende vejledning – Del 3

Den følgende tutorial-serie består af tre artikler, der lærer dig forskellige aspekter om Hyperledger Fabric-kædeudvikling lige fra CRUD-operationer, databeskyttelse og kædekodetest.

Del 1

Del 2

Del 3

Hyperledger Fabric Tutorial: Omfattende vejledning - Del 2

En oversigt over serien:

  • Artikel 1: Grundlæggende kædekodeudvikling og lagring af private data i samlinger
  • Artikel 2: Avancerede kædekodeforespørgsler og CouchDB GUI
  • Artikel 3: En vejledning i retning af at teste din kædekode med MockStub

Krav

  • 4 GB RAM (mere foretrækkes)
  • Docker, Docker-Compose, kodeditor (f.eks. Visual Studio Code), Git
  • NodeJS version 8.9+ (Foretrukket er 8.9.4 – Tip: skift din version med en version manager som ‘n‘)
  • Grundlæggende JavaScript-viden

Mål

  • Lær at teste dine kædekodefunktioner
  • Lær at spotte og påberåbe sig funktioner
  • Sammenlign resultater med Chai-test

Introduktion

I de to foregående artikler har vi lært at oprette begge grundlæggende som mere avancerede kædekodefunktioner. Vigtigheden af ​​at teste din kædekode kan ikke undervurderes. En enkelt fejl kan have dramatiske konsekvenser, når man beskæftiger sig med smarte kontrakter. Derfor sætter vi kvaliteten af ​​vores kædekodefunktioner på prøve.

Kom igang

Sørg for, at du har en kopi af koden, som kan findes på Github michielmulders / hyperledger-fabric-blockgeeks. Det anbefales at bruge git klon https://github.com/michielmulders/hyperledger-fabric-blockgeeks.git for at oprette en lokal klon af lageret på din maskine. Brug git checkout tutorial-3 for at åbne koden til denne tutorial og tjekke den tredje del af tutorialen med git checkout tutorial-3

Hvis du er ny med denne vejledning, skal du tjekke afsnittet ‘Opsætning af kedelplade’ i den første artikel for at komme i gang.

Lad os nu navigere med din terminal til kædekode / knude folder. Herfra kan vi løbe npm-kørselstest for at starte vores test. Selve testene findes på kædekode / node / tests / tests.spec.ts. Lad os se på disse tests.

Test ved hjælp af Mockstub

Jonas Snellinckx fra TheLedger forklarer, hvad ChaincodeMockStub er, ”Denne ChaincodeMockStub er en mock-implementering af stof-shim-stubben. Dette betyder, at du kan teste din kædekode uden faktisk at starte dit netværk. Det implementerer næsten enhver funktion, som den faktiske stub udfører, men i hukommelsen. Kun disse funktioner understøttes (endnu) ikke: getHistoryForKey, getBinding, getTransient, setEvent, getChannelID. ”

Kædekodetest

For at komme i gang skal vi importere ‘forvent’ -funktionaliteten fra Chai testpakke, så vi kan bruge forskellige sammenligningsmekanismer som at sammenligne responsobjekter eller statuskoder. Chai er et BDD / TDD-påstandsbibliotek til node og browseren, der kan parres dejligt med enhver javascript-testramme.

importer {forvent] fra “chai”;

Hvis du kigger på tests.spec.ts fil, kan du se, at vi grupperer tests sammen med beskrive funktion, dette er bare en generel kodestil praksis. Dernæst bruger vi det funktion til at definere individuelle tests.

De fleste tests starter med at oprette en ny forekomst af vores kædekode. Dette er ikke altid nødvendigt, da vi også kan definere en global forekomst af vores kædekode, som vi kan ringe til og påkalde funktioner på fra hver test. Dette afhænger af, hvordan og hvad du vil teste, for det meste vil vi prøve at skrive enhedstest, bare teste kernefunktionaliteten for en funktion. Det meste af tiden definerer vi en ny kædekodeforekomst, men vi vil også instantere en global kædekodeforekomst med instantierede bildata, der kan bruges i flere tests. Lad os skrive vores første tests!

1. Færdiggørelse af første kædekode

Test InitLedger

Først og fremmest starter vores netværk med at ringe til initLedger funktion, der udfylder vores blockchain med bildata. For at sikre, at resten af ​​vores kædekode fungerer korrekt, skal vi teste status for denne funktion og kontrollere, om alle data er til stede i blockchain-tilstand.

Vi starter med at importere kædekoden og oprette en instans, så vi kan få adgang til alle de funktioner, vi har defineret.

importere {MyChaincode} fra ‘../src/MyChaincode’;

const chaincode = ny MyChaincode ();

Dernæst kan vi definere vores første testsag, give den en meningsfuld beskrivelse. Som du kan se, definerer vi en ny mockstub-forekomst, som vi kun vil bruge i denne test, da vi vil være sikre på, at vores kædekode kompileres korrekt. Det mockInit funktion initialiserer kædekoden (kalder initLedger-funktionen). Vi giver det et unikt transaktions-id tx1 og videregive et tomt array, da det ikke kræver nogen argumenter. Når kædekoden initialiseres, vil vi teste udførelsesstatus og sikre, at alt var vellykket. Den samme metode som Chai forventer funktionalitet er praktisk til at sammenligne status.

det("Bør init uden problemer", asynkronisering () => {

       const stub = ny ChaincodeMockStub ("MyMockStub", kædekode);

       const respons = afventer stub.mockInit ("tx1", []);

       forvent (respons.status) .to.eql (200)

});

Både mockInit og mockInvoke funktion returner følgende løfteobjekt:

Løfte<{

   status: nummer;

   besked: streng;

   nyttelast: Buffer;

}>

Bekræft initialiserede data

I øjeblikket er vi sikre på, at kædekoden er kompileret og initialiseret korrekt. Vi er dog ikke sikre på, om alle data er korrekt tilføjet til vores blockchain-tilstand. Lad os teste forespørgslen om al funktionalitet for at sammenligne de returnerede bilgenstande med de forventede biler.

Denne gang opretter vi en global forekomst af kædekodemockstub.

det("Bør være i stand til at starte og spørge alle biler", asynkronisering () => {

       stubWithInit = ny ChaincodeMockStub ("MyMockStub", kædekode);

       …

}

Denne gang, den mockInvoke funktionen bruges til at påkalde queryAllCars-funktionen i kædekoden. Det queryResponse.payload indeholder en buffer, som vi kan bruge i vores sammenligningsfunktion. TheLedger har leveret en hjælper, der konverterer en Buffer-nyttelast til et JSON-objekt ved hjælp af Transformer hjælper fra @ theledger / stof-mock-stub. Forventningsfunktionen indeholder en dyb metode, der fuldt ud kan sammenligne JSON-objekter. Vi sammenligner resultatet med de oprindelige objekter, vi har defineret i initLedger fungere.

const queryResponse = afventer stubWithInit.mockInvoke ("txID2", ["queryAllCars"]);

forvent (Transform.bufferToObject (queryResponse.payload)). til.deep.eq ([

           {

               mærke: ‘Toyota’,

               model: ‘Prius’,

               farve: ‘blå’,

               ejer: ‘Tomoko’,

               docType: ‘bil’,

               nøgle: ‘CAR0’

           },

       ])

   });

2. Test Opret bil

Lad os påberåbe sig bilobjektet i en ny test sag. Dette er et godt eksempel, da det lærer os, hvordan vi sender argumenter til mockInvoke-funktionaliteten. Denne test består af to komponenter. Først tilføjer vi den nye bil til blockchain-tilstanden, næste bliver bilen spurgt om at sammenligne begge objekter.

const stub = ny ChaincodeMockStub ("MyMockStub", kædekode);

const respons = afventer stub.mockInvoke ("tx1", [‘createCar’, JSON.stringify ({

      nøgle: ‘CAR0’,

      lave: "prop1",

      model: "prop2",

      farve: "prop3",

      ejer: ‘ejer’

})]);

forvent (respons.status) .to.eql (200)

Som du kan se, kan vi videregive et fuldt strenget JSON-objekt til mockInvoke funktion, der indeholder alle egenskaberne til oprettelse af det nye bilobjekt. Efter oprettelse af bilen bekræfter vi udførelsesstatus.

Nu er bilen tilføjet, vi kan spørge den igen for at bruge den i vores sammenligningsfunktionalitet. Vi passerer nøglen til bilen, vi lige har oprettet ‘CAR0’ og udfører en dyb-lige.

3. Test af private samlinger

Okay, vi har indtastet den sidste del af denne tutorial, hvor vi vil teste dataindsigt private samlinger. Igen har mockstub et alternativ i hukommelsen til private samlinger, så vi behøver ikke starte vores Hyperledger Fabric-netværk.

Igen er det første, vi vil gøre, at videregive argumenterne for at oprette vores private bil via createPrivateCar fungere.

const stub = ny ChaincodeMockStub ("MyMockStub", kædekode);

const respons = afventer stub.mockInvoke ("tx1", [‘createPrivateCar’, JSON.stringify ({

    nøgle: ‘CAR0’,

    lave: "prop1",

    model: "prop2",

    farve: "prop3",

    ejer: ‘ejer’

})]);

forvent (respons.status) .to.eql (200);

Ok, lad os sammenligne det forventede objekt med objektet fra den private samling i hukommelsen. Stubben er smart nok til at oprette samling i hukommelsen, når du påberåber kædekodefunktionen. Det stub.privateCollections har en matrix med alle private datasamlinger, og vi specificerer, hvilken samling vi ønsker, og hvilket objekt der skal hentes fra denne samling. Dette objekt kan matches med det forventede bilobjekt.

forvent (Transform.bufferToObject (stub.privateCollections ["privateCarCollection"] ["CAR0"til.deep.eq ({

           ‘make’: ‘prop1’,

           ‘model’: ‘prop2’,

           ‘farve’: ‘prop3’,

           ‘ejer’: ‘ejer’,

           ‘docType’: ‘bil’

       })

Kør alle test

Ok, det er tid til at køre vores tests igen, brug npm-kørselstest. Hvis alt går godt, skal du se et godt overblik over, hvad der skete for hver test og dens resultat. Koden skal gengive 8 beståede resultater som vist nedenfor.

Hvad lærte vi?

ChaincodeMockStub er virkelig nyttig, da det giver en udvikler mulighed for at teste sin kædekode uden at starte netværket hver gang. Dette reducerer udviklingstid, da han kan bruge en testdrevet udviklingsmetode (TDD), hvor han ikke behøver at starte netværket (dette tager + – 40-80 sekunder afhængigt af computerens specifikationer). Adgang til private samlinger i hukommelsen er også meget ligetil via stub.privateCollections array. Du har kun brug for et par af Chai’s testfunktioner som dybden, der svarer til korrekt at teste din kædekode.

Kode Cheatsheet

  1. Opret forekomst af kædekode, der kalder initLedger-funktionen.

afventer stub.mockInit ("tx1", []);

  1. Påkald en normal funktion og send argumenter.

    const respons = afventer stub.mockInvoke ("tx1", [‘createCar’, JSON.stringify ({

          CarObject…

    })]);

    3. Start en kædekodefunktion, der bruger private samlinger og videregive argumenter.

afventer stub.mockInvoke ("tx1", [‘createPrivateCar’, JSON.stringify ({

    CarObject…

})]);

  1. Standard svarløfte returneret fra begge mockInit og mockInvoke:

Løfte<{

   status: nummer;

   besked: streng;

   nyttelast: Buffer;

}>

Yderligere læser

Mike Owergreen Administrator
Sorry! The Author has not filled his profile.
follow me