Kujaribu mkataba-erevu rahisi kwa kutumia maktaba ya Waffle
Katika mafunzo haya utajifunza jinsi ya
- Jaribu mabadiliko ya salio la mkoba
- Jaribu utoaji wa matukio na hoja maalum
- Thibitisha kuwa muamala ulirejeshwa
Dhana
- Unaweza kuunda mradi mpya wa JavaScript au TypeScript
- Una uzoefu wa kimsingi na majaribio katika JavaScript
- Umetumia wasimamizi wengine wa vifurushi kama vile yarn au npm
- Una ufahamu wa kimsingi sana wa mikataba-erevu na Solidity
Kuanza
Mafunzo haya yanaonyesha usanidi na uendeshaji wa jaribio kwa kutumia yarn, lakini hakuna shida ikiwa unapendelea npm - nitatoa marejeleo sahihi kwa nyarakaopens in a new tab rasmi za Waffle.
Sakinisha Vitegemezi
Ongezaopens in a new tab vitegemezi vya ethereum-waffle na typescript kwenye vitegemezi vya dev vya mradi wako.
yarn add --dev ethereum-waffle ts-node typescript @types/jestMfano wa mkataba-erevu
Wakati wa mafunzo haya tutafanyia kazi mfano rahisi wa mkataba-erevu - EtherSplitter. Haufanyi mengi isipokuwa kuruhusu mtu yeyote kutuma wei fulani na kuigawanya sawasawa kati ya wapokeaji wawili waliobainishwa awali. Kitendaji cha kugawanya kinahitaji namba ya wei iwe shufwa, vinginevyo kitarejeshwa. Kwa wapokeaji wote wawili hufanya uhamisho wa wei ikifuatiwa na utoaji wa tukio la Uhamisho.
Weka kipande cha msimbo wa EtherSplitter katika src/EtherSplitter.sol.
1pragma solidity ^0.6.0;23contract EtherSplitter {4 address payable receiver1;5 address payable receiver2;67 event Transfer(address from, address to, uint256 amount);89 constructor(address payable _address1, address payable _address2) public {10 receiver1 = _address1;11 receiver2 = _address2;12 }1314 function split() public payable {15 require(msg.value % 2 == 0, 'Uneven wei amount not allowed');16 receiver1.transfer(msg.value / 2);17 emit Transfer(msg.sender, receiver1, msg.value / 2);18 receiver2.transfer(msg.value / 2);19 emit Transfer(msg.sender, receiver2, msg.value / 2);20 }21}Onyesha yoteKusanya mkataba
Ili kukusanyaopens in a new tab mkataba ongeza ingizo lifuatalo kwenye faili la package.json:
1"scripts": {2 "build": "waffle"3 }Ifuatayo, unda faili la usanidi la Waffle katika saraka kuu ya mradi - waffle.json - na kisha ubandike usanidi ufuatao hapo:
1{2 "compilerType": "solcjs",3 "compilerVersion": "0.6.2",4 "sourceDirectory": "./src",5 "outputDirectory": "./build"6}Endesha yarn build. Kama matokeo, saraka ya build itaonekana na mkataba wa EtherSplitter uliokusanywa katika muundo wa JSON.
Usanidi wa Jaribio
Kujaribu na Waffle kunahitaji kutumia vilinganishi vya Chai na Mocha, kwa hivyo unahitaji kuwaongezaopens in a new tab kwenye mradi wako. Sasisha faili yako ya package.json na ongeza ingizo la test katika sehemu ya scripts:
1"scripts": {2 "build": "waffle",3 "test": "export NODE_ENV=test && mocha -r ts-node/register 'test/**/*.test.ts'"4 }Ikiwa unataka kutekelezaopens in a new tab majaribio yako, endesha tu yarn test .
Kujaribu
Sasa unda saraka ya test na unda faili mpya test\EtherSplitter.test.ts.
Nakili kipande kilicho hapa chini na ukibandike kwenye faili letu la majaribio.
1import { expect, use } from "chai"2import { Contract } from "ethers"3import { deployContract, MockProvider, solidity } from "ethereum-waffle"4import EtherSplitter from "../build/EtherSplitter.json"56use(solidity)78describe("Ether Splitter", () => {9 const [sender, receiver1, receiver2] = new MockProvider().getWallets()10 let splitter: Contract1112 beforeEach(async () => {13 splitter = await deployContract(sender, EtherSplitter, [14 receiver1.address,15 receiver2.address,16 ])17 })1819 // add the tests here20})Onyesha yoteManeno machache kabla ya kuanza.
MockProvider huja na toleo la mfano la mnyororo wa bloku. Pia hutoa mikoba ya mfano ambayo itatusaidia kwa kujaribu mkataba wa EtherSplitter. Tunaweza kupata hadi mikoba kumi kwa kuita mbinu ya getWallets() kwenye mtoa huduma. Katika mfano, tunapata mikoba mitatu - kwa mtumaji na kwa wapokeaji wawili.
Ifuatayo, tunatangaza kigezo kinachoitwa 'splitter' - huu ni mkataba wetu wa mfano wa EtherSplitter. Inaundwa kabla ya kila utekelezaji wa jaribio moja kwa mbinu ya deployContract. Mbinu hii inaiga upelekaji wa mkataba kutoka kwenye mkoba uliopitishwa kama kigezo cha kwanza (mkoba wa mtumaji katika kesi yetu). Kigezo cha pili ni ABI na bytecode ya mkataba unaojaribiwa - tunapitisha hapo faili la json la mkataba wa EtherSplitter uliokusanywa kutoka kwenye saraka ya build. Kigezo cha tatu ni safu yenye hoja za kiunda mkataba, ambazo katika kesi yetu, ni anwani mbili za wapokeaji.
changeBalances
Kwanza, tutaangalia ikiwa mbinu ya kugawanya inabadilisha salio kweli la mikoba ya wapokeaji. Ikiwa tutagawanya wei 50 kutoka kwa akaunti ya mtumaji, tutarajia salio la wapokeaji wote wawili kuongezeka kwa wei 25. Tutatumia kilinganishi cha changeBalances cha Waffle:
1it("Changes accounts balances", async () => {2 await expect(() => splitter.split({ value: 50 })).to.changeBalances(3 [receiver1, receiver2],4 [25, 25]5 )6})Kama kigezo cha kwanza cha kilinganishi, tunapitisha safu ya mikoba ya wapokeaji, na kama ya pili - safu ya ongezeko linalotarajiwa kwenye akaunti husika.
Ikiwa tungetaka kuangalia salio la mkoba mmoja maalum, tungeweza pia kutumia kilinganishi cha changeBalance, ambacho hakihitaji kupitisha safu, kama katika mfano hapa chini:
1it("Changes account balance", async () => {2 await expect(() => splitter.split({ value: 50 })).to.changeBalance(3 receiver1,4 255 )6})Kumbuka kuwa katika visa vyote viwili vya changeBalance na changeBalances tunapitisha kitendaji cha kugawanya kama simurejeshi kwa sababu kilinganishi kinahitaji kufikia hali ya salio kabla na baada ya wito.
Ifuatayo, tutajaribu ikiwa tukio la Uhamisho lilitolewa baada ya kila uhamisho wa wei. Tutaelekea kwenye kilinganishi kingine kutoka Waffle:
Emit
1it("Emits event on the transfer to the first receiver", async () => {2 await expect(splitter.split({ value: 50 }))3 .to.emit(splitter, "Transfer")4 .withArgs(sender.address, receiver1.address, 25)5})67it("Emits event on the transfer to the second receiver", async () => {8 await expect(splitter.split({ value: 50 }))9 .to.emit(splitter, "Transfer")10 .withArgs(sender.address, receiver2.address, 25)11})Onyesha yoteKilinganishi cha emit kinaturuhusu kuangalia ikiwa mkataba ulitoa tukio wakati wa kuita mbinu. Kama vigezo vya kilinganishi cha emit, tunatoa mkataba wa mfano ambao tunatabiri utatoa tukio, pamoja na jina la tukio hilo. Katika kesi yetu, mkataba wa mfano ni splitter na jina la tukio - Transfer. Tunaweza pia kuthibitisha thamani kamili za hoja ambazo tukio lilitolewa nazo - tunapitisha hoja nyingi kwenye kilinganishi cha withArgs, kama tamko letu la tukio linavyotarajia. Katika kesi ya mkataba wa EtherSplitter, tunapitisha anwani za mtumaji na mpokeaji pamoja na kiasi cha wei kilichohamishwa.
revertedWith
Kama mfano wa mwisho, tutaangalia ikiwa muamala ulirejeshwa ikiwa nambari ya wei si shufwa. Tutatumia kilinganishi cha revertedWith:
1it("Reverts when Vei amount uneven", async () => {2 await expect(splitter.split({ value: 51 })).to.be.revertedWith(3 "Uneven wei amount not allowed"4 )5})Jaribio, likifaulu, litatuhakikishia kwamba muamala ulirejeshwa kweli. Hata hivyo, lazima pia kuwe na mlingano kamili kati ya ujumbe tuliouweka katika taarifa ya require na ujumbe tunaotarajia katika revertedWith. Tukirudi kwenye msimbo wa mkataba wa EtherSplitter, katika taarifa ya require kwa kiasi cha wei, tunatoa ujumbe: 'Uneven wei amount not allowed'. Huu unalingana na ujumbe tunaotarajia katika jaribio letu. Kama hazingekuwa sawa, jaribio lingefeli.
Hongera!
Umechukua hatua yako kubwa ya kwanza kuelekea kujaribu mikataba-erevu na Waffle!
Ukurasa ulihaririwa mwisho: 17 Desemba 2025