mocha測試框架-truffle


https://mochajs.org/
學習網址:
https://www.jianshu.com/p/9c78548caffa
https://www.jb51.net/article/106463.htm
在truffle框架的簡單使用中,我們了解到它的測試模塊是包裝了mocha測試框架的,在這里我們選擇cryptopunks的truffle例子來相應講解:

https://github.com/larvalabs/cryptopunks

 

為什么要使用mocha這個測試模塊:

當我們在開發,我們往往會有以下的問題:

參考:https://blog.csdn.net/imwebteam/article/details/53310958

需求和開發脫節

當一份需求來了, 開發人員往往不能百分百的理解需求的內容(拋棄產品自己變更需求的可能性。。),這往往會讓開發人員開發出的功能會有跟需求有所差別,這會帶來額外的工作量

開發和測試脫節

什么是開發和測試脫節,說的是,當開發人員按照自己的想法開發完了一個需求。然后測試人員也按照自己的想法去測試這個需求,然后由於雙方的分歧,導致測試認為開發有bug,開發認為測試是sb.

那么如何解決上面的問題呢?

答案就是 選擇一種軟件敏捷開發模式

敏捷開發模式

目前比較流行的開發模式有兩種: TDD 和 BDD

TDD (Test Driven Development 測試驅動開發)

  • 測試來驅動開發
  • 其重點偏向開發
  • 測試用例是在約束開發者,使開發者的目標明確,設計出滿足需求的系統

BDD (Behaviour Driven Development 行為驅動開發)

  • 基於TDD發展,保持測試先行的理念
  • 其重點偏向設計
  • 在測試代碼中用一種自然通用語言的方式把系統的行為描述出來
  • 將系統的設計和測試用例結合起來,進而驅動開發工作

兩種方式各有其特點,我們通常選擇的是BDD的方式

為了方便我們編寫測試用例,我們需要使用一些前端測試用例工具——mocha

 

在這個例子中我們能夠看見在其的test文件夾中寫了一些測試文件,比如我們以cryptopunksmarket-setinitia.jsl這個文件為例,看cryptopunks測試代碼cryptopunksmarket-setinitial.js

(1)Truffle測試框架學習:

參考:http://www.blockchainbrother.com/article/2082

Truffle 使用 Mocha 測試框架 和 Chai 斷言來給你提供一個可靠的框架編寫JavaScript測試。這里需要注意到的一個很大的不同是它使用了contract()測試套件替代了describe()測試套件,這個函數基本和 describe() 一樣,只不過它可以啟用clean-room 功能.  其過程如下:

     1. 每次contract()函數運行之前,您的合約會被重新部署到正在運行的以太坊客戶端,因此測試是在一個干凈的合約環境下進行的。
     2. 這個contract()函數提供一個由您的以太坊客戶端生成的,可以在編寫測試合約使用的賬戶列表。
比如:
contract('CryptoPunksMarket-setInitial', function (accounts) {});
在這里accounts就是會返回在區塊鏈環境上的所有用戶的賬戶來讓測試使用
 
如果您不需要一個清潔的測試環境,那么您仍然可以使用describe()函數來運行普通的Mocha測試。
 
Truffle 無法檢測出在測試中需要與哪些合約進行交互,所以您需要明確地指出這些合約。您可以使用一個由Truffle提供的方法 artifacts.require()來做這些事情,它可以讓您為一個特定的合約,請求一個可用的合約抽象。
比如:var CryptoPunksMarket = artifacts.require("./CryptoPunksMarket.sol");
在測試中使用artifacts.require()的方式和在遷移中使用的方式相同,您只需要指定合約名稱,比如:
var CryptoPunksMarket = artifacts.require("CryptoPunksMarket");
CryptoPunksMarket就是在contracts文件夾中的智能合約文件的名字
 
因為truffle中已經將斷言庫  Chai 也包裝了進去,所以當想使用斷言,如assert時,可以直接使用,不用導入模塊
其他的部分基本上就與mocha相同了,詳細內容繼續往下看

(2)后面想要使用測試框架mocha,但是又不想使用truffle,所以就來學習這個框架怎么單獨使用了,下面就是學習的過程:
當然,首先要安裝:

使用npm全局安裝:
npm install --g mocha
或者僅僅只是安裝在某個模塊:

npm install --save mocha
然后你就可以使用了

1.要測試上面的代碼是否對的,因此就要編寫測試腳本,測試腳本與所要測試的源碼腳本同名,但是后綴名為 .test.js或 .spec.js, 如:xx.test.js 或 xx.spec.js

2.測試腳本可以包含一個或多個describe塊,describe塊稱為 "測試套件",表示一組相關的測試,它是一個函數,有兩個參數,第一個參數是測試套件的名稱,第二個參數是一個實際執行的函數。
每個describe塊也可以包含一個或多個it塊,it塊稱為 “測試用例",表示一個單獨的測試,是測試的最小單位,它也是一個函數,第一個參數也是測試用例的名稱,第二個參數是一個實際執行的函數,it塊之間是同步運行的。

describe 和 it 大量嵌套后,就形成了一顆樹。樹的非葉子節點都是測試集合,葉子節點即 it ,就是測試用例。

注意,如果一個describe 里面沒有 it (比如下面:), Mocha將不會執行這個 describe。

3.理解斷言庫

學習文檔:http://www.chaijs.com


斷言庫可以理解為比較函數,也就是斷言函數是否和預期一致,如果一致則表示測試通過,如果不一致表示測試失敗。mocha本身是不包括斷言庫的,所以必須引入第三方斷言庫的,目前比較受歡迎的斷言庫有 should.js, expect.js, chai.
should.js是BDD風格
expect.js是expect風格的斷言
//下面介紹的是chai


chai的expect(), assert() 和 should的斷言
Mocha默認使用的是BDD的風格。expect和should都是BDD的風格,二者使用相同的鏈式語言來組織斷言的,但不同在於他們初始化斷言的方式,expect使用
構造函數來創建斷言對象實例,而should通過為 Object.prototype新增方法來實現斷言(should不支持IE),expect直接指向 chai.expect,
should則是 chai.should();
上面的代碼中 expect 是斷言的意思,該作用是判斷源碼的實際執行結果與預期結果是否一致,如果不一致就拋出一個錯誤

三種的使用方法簡單如下所示:

var expect = require('chai').expect;

expect(2).to.be.equal(2);

 

var assert = require('chai').assert;

assert.equal((await contract.totalSupply()).toNumber(), 10);

 

var should = require('chai').should();

cookies.should.not.be.empty;

cookies.id.should.equal('10001','not equal to 10001');

因此在執行上面代碼之前,
我們需要在項目中安裝 chai, 如下命令:
npm install --save-dev chai

1)var expect = require('chai').expect;
即引用 chai 斷言庫,使用的是 expect斷言風格。
expect 官網API(http://chaijs.com/api/bdd/).


2)mocha測試代碼如何運行?
上面的add.test.js 編寫完成后,我們需要運行測試代碼了,進入add.test.js代碼的目錄后,執行如下命令可運行:
mocha add.test.js

mocha命令后面也可以指定多個文件,如下命令:
mocha xx.test.js yy.test.js
使用通配符:
或者我們可以運行如下命令,執行多個測試腳本文件:
mocha spec/{add,reduce}.js //目錄spec下的add.js和reduce.js文件
mocha spec/*.js //所有文件
mocha默認運行test子目錄里面的測試腳本,我們一般情況下,可以把測試腳本放在test目錄下,然后進入test的上層目錄,直接執行mocha命令即可:
mocha
然后你就會發現test目錄下第一層的所以測試文件都被運行了。命令只會執行test第一層目錄下所有文件,並不能執行嵌套目錄下的文件。
為了執行所有嵌套目錄下的文件,我們可以 mocha命令后面加一個參數 --recursive 參數
更多的細節信息可以看:https://www.cnblogs.com/tugenhua0707/p/8419534.html,當然之后你要補充一下

 


3)測試用例的鈎子
Mocha在describe塊之中,提供了測試用例的四個鈎子,before(), after(), beforeEach()和afterEach(),他們會在指定的時間內執行。
before(): 將會在所有測試用例執行之前運行,比如在之前插入數據等等操作。
after(): 會在所有測試執行之后運行,用於清理測試環境,回滾到清空數據狀態。
beforeEach(): 將會在每個測試用例執行之前執行,可用於測試測試需要准備相關數據的條件。
afterEach(): 將會在每個測試用例之后執行,可用於准備測試用例所需的后置條件。

4)理解異步鈎子函數
例子1:
var expect = require('chai').expect;
describe('異步鈎子函數', function() {
  var foo = false;
  beforeEach(function(){
    setTimeout(function(){
      foo = true;
    }, 50)
  });
  it('異步鈎子函數成功', function() {
    expect(foo).to.be.equal(true);
  })
});

結果:
異步鈎子函數
       異步鈎子函數成功:

      AssertionError: expected false to equal true
      + expected - actual

      -false
      +true

如上可以看到測試失敗,原因是因為setTimeout 是異步的,在setTimeout執行完之前,it函數已經被執行了,所以foo當時數據還是false,
因此false不等於true了。


這時候 done參數出來了,在回調函數存在時候,它會告訴mocha,你正在編寫一個異步測試,會等到異步測試完成的時候來調用done函數,或者超過2秒后超時,如下代碼就可以成功了;
var expect = require('chai').expect;
describe('異步鈎子函數', function() {
  var foo = false;
  beforeEach(function(done){
    setTimeout(function(){
      foo = true;
      // complete the async beforeEach
      done();
    }, 50)
  });
  it('異步鈎子函數成功', function() {
    expect(foo).to.be.equal(true);
  });
});

(3)這篇文章不是要很詳細地告訴大家概念性的內容,只是讓有跟我一樣想法(即學習了truffle框架后,發現里面的那個測試十分有意思,想之后做測試的時候也用這種測試方法),但是突然不知道怎么入手的人一個方向,知道那是個什么測試框架,以及去哪里學習,以及一些比較簡單的必須知道的概念和內容,知道這些其實你就可以寫一個十分簡單的測試例子了,建議結合別人的測試代碼進行學習,如https://github.com/larvalabs/cryptopunks/tree/master/test

在下面進行測試:

1)一開始,當我想要直接復制truffle中寫好的測試文件,進行小部分更改直接進行使用時,發現出錯:

truffle中只需要這兩句話就可以部署好合約,但是在沒框架的情況下是不可以的
var testToken = artifacts.require(“./test-punk.sol”);
instance = await testToken.deployed(50);

這樣會報錯:
1.ReferenceError: artifacts is not defined
2.(function (exports, require, module, __filename, __dirname) { pragma solidity ^0.4.20;
                                                                     ^^^^^^^^
SyntaxError: Unexpected identifier

所以這就說明了在框架外是不可以這樣子進行合約的編譯的

通過上面我們就能夠知道truffle到使用上面兩句部署指令前,還進行了編譯compile和部署migrate,所以在測試前要將合約的編譯和部署都弄好,你可以通過查看我寫的remix的使用來學怎么使用remix進行編譯和部署或者是看nodejs部署智能合約的方法來自己編寫代碼進行編譯和部署,最終得到合約的部署地址NFMAddress

部署成功后,之后如果想在別的地方進行使用,需要以下幾句話句話:

const NFMAbi = require("./testToken.json");//合約生成的Abi,一般為json文件

const NFMContract = web3.eth.contract(NFMAbi);
const instance = NFMContract.at(NFMAddress);

此時就能夠調用該函數中的函數及變量了

 

2)其次,還要記得將相應的模塊包下載下來,這里要添加package.json文件配置等內容

Error: Cannot find module ‘web3'
你安裝的web3一定要放在本地的node_modules文件夾下,不然是讀不出來的

3)使用nodejs來進行合約的編譯和部署時,發現出現下面的錯誤
1.let abi = compiledContract.contracts['testToken'].interface;
出錯:
TypeError: Cannot read property 'interface' of undefined

然后輸出compiledContract進行查看
2.console.log(compiledContract);
發現在編譯處就出錯了
{ contracts: {},
  errors:
   [ ':49:17: ParserError: Expected identifier, got \'LParen\'\n    constructor (uint number) public{\n                ^\n' ],
  sourceList: [ '' ],
  sources: {} }
還有:
{ contracts: {},
  errors:
   [ ':26:9: TypeError: Wrong argument count for function call: 2 arguments given but expected 1.\n        require(propertyValueToOwner[propertyValue] == 0x0,\'this is not the first-sell\');\n        ^------------------------------------------------------------------------------^\n',
發現可能是版本的問題,因為這里聲明構造函數使用了新的聲明方式,但是在這里沒能被識別出。所以下載了新版本的solc,然后就成功了

4)

contract('testToken',async (accounts) => {
出錯:ReferenceError: contract is not defined
因為contract是truffle框架弄的,不在框架中是不能夠這樣使用的,這時候想要使用賬號只能老實地連接區塊鏈,通過web3模塊去調用API接口

var Web3 = require("web3");

web3.setProvider(new Web3.providers.HttpProvider("http://localhost:8201"));

account1 = web3.eth.accounts[0];


5)最后運行結果也有問題:
用戶deMBP:testToken 用戶$ mocha test-mocha.js

  testToken Test
check tokenNumber
    1) deploy contract
    2) sell token
    3) buy token
    4) check the balance
    5) withdrawl the balance


  0 passing (118ms)
  5 failing

  1) testToken Test
       deploy contract:
     TypeError: Cannot read property 'call' of undefined
      at Context.<anonymous> (test-mocha.js:56:43)

  2) testToken Test
       sell token:
     TypeError: Cannot read property 'sellToken' of undefined
      at Context.<anonymous> (test-mocha.js:77:19)

  3) testToken Test
       buy token:
     TypeError: Cannot read property 'testTokenIdToOwner' of undefined
      at Context.<anonymous> (test-mocha.js:90:25)

  4) testToken Test
       check the balance:
     TypeError: Cannot read property 'pendingDrawalOfUser' of undefined
      at Context.<anonymous> (test-mocha.js:112:38)

  5) testToken Test
       withdrawl the balance:
     TypeError: Cannot read property 'pendingDrawalOfUser' of undefined
      at Context.<anonymous> (test-mocha.js:124:31)

Contract mined! address: 0x3cb4464f73eda60ac3ba1d46cd0544cd7ae18040 transactionHash: 0x62f27e3ccdfcb6ba54547107bbc8f1f9f152f0f588eddec9b1dc3a65d1d7d047

后面發現這個原因是部署回調得到instance前,it函數中的內容就已經開始調用了,這樣的話怎么着instance都是undefined的,那么肯定是不可能能夠調用合約中的函數的。而且在這里將部署函數放在了一個單獨的it測試用例當中,但是下面的測試用例都是應該等待部署完成后才能夠測試成功的,那么這樣就不可能成功測試了,因為it測試用例是同步進行的,在部署的同時,其他測試用例也都開始運行了,⚠️有前后關系的測試內容應該要寫在一個測試用例當中。


所以就不做在這之前進行部署的事情了,畢竟我們肯定在測試之前是已經把合約部署上去的了,那么只要用
let instance = MyContract.at('0x86757c9bdea10815e7d75a1577b6d9d2825dae0a');
這句話就行了

6)然后再運行也出錯:
mocha Error: Timeout of 2000ms exceeded.
則需要你再運行的時候添加
mocha -t 20000 test.js
因為其默認的時間是2000ms,你的時間如果過大,可以進行自己設置

7)當你使用describe這些mocha的形式語句的時候,使用node test.js是不能運行成功的,會返回錯誤:

用戶MBP:testToken 用戶$ node test.js
/Users/用戶/testToken/test.js:165
describe('testToken',function(){
^
ReferenceError: describe is not defined

所以一定要用mocha開頭,mocha test.js

實現:

const debug = require("debug")("testToken");
const assert = require('assert')
// var testToken = require("./test-punk.sol");
const Web3 = require('web3');
const web3 = new Web3();
web3.setProvider(new Web3.providers.HttpProvider('http://127.0.0.1:7545'));
const fs = require("fs");
const solc = require("solc");
let source = fs.readFileSync("testToken.sol",'utf8');//read file
let compiledContract = solc.compile(source,1);//compile
// console.log(compiledContract);

for (let contractName in compiledContract.contracts) { 
    console.log("in");
    var bytecode = compiledContract.contracts[contractName].bytecode;
    var abi = JSON.parse(compiledContract.contracts[contractName].interface); //將abi寫成json形式
    console.log("out");

} 
// 你要測試的是接口
// console.log(bytecode);
// console.log(abi);

let gasEstimate = web3.eth.estimateGas({data:'0x'+bytecode});
let MyContract = web3.eth.contract(abi);
debug("deploying contract");
// let instance;
let instance = MyContract.at('0x86757c9bdea10815e7d75a1577b6d9d2825dae0a');//可改


var user1 = web3.eth.accounts[0];
console.log(user1);
var user2 = web3.eth.accounts[1];
var user3 = web3.eth.accounts[2];
var user4 = web3.eth.accounts[3];
var user5 = web3.eth.accounts[4];
var propertyValues = ['0x00000001','0x00000002','0x00000003','0x00000004','0x00000005'];
var prices = [11,12,13,14,15];
var users = [user1,user2,user3,user4,user5];

//這個地方是想要在這里同時部署合約,但是發現總是不成功,部署異步總是太慢,before()函數好像也沒有什么用,所以后面我也只能放棄部署了,只能先部署完得到地址再來調用了
// function deployContract() {
//     instance = MyContract.new(50,{from:user1,data:'0x'+bytecode,gas:47000000},function(e,contract){
//             if(typeof contract.address !== 'undefined'){
//                 console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);
//             }
//     });
// }
// before(deployContract);
// var instance;
describe("testToken Test",function(){

    // it("deploy contract",async function(){


    it("contract begin",async function(){

        let num = propertyValues.length;
        // instance = await testToken.deployed(50);

        console.log(instance.address);
        console.log('check tokenNumber');
        console.log(await instance.tokenNumber.call());
        debug("create token");
     //首先先創建5個token
for(let i=0; i<num; i++){ await instance.create(propertyValues[i],prices[i],{from:users[i],value:prices[i],gas:30000000}); } debug("display token");
     //然后查看生成的token的屬性 let nextTokenId
= await instance.nextTokenToCreate.call(); console.log("nextTokenId is :"+ nextTokenId); if(parseInt(nextTokenId) != 5){ console.log("initial token failed"); }else{ for(let i =0; i<num; i++){ console.log(await instance.propertyOfToken.call(i)); } } });   //然后sell token it("sell token",async function(){ await instance.sellToken(0,21,{from:user1,gas:30000000}); await instance.sellToken(1,22,{from:user2,gas:30000000});      //查看是否成功sell console.log(await instance.tokenIdToSell.call(0)); console.log(await instance.tokenIdToSell.call(1)); });    //其他用戶對sell的token進行購買 it("buy token",async function(){
     //查看購買前token的擁有者是誰 console.log(instance.testTokenIdToOwner.call(
0)); console.log(instance.testTokenIdToOwner.call(1)); await instance.buyToken(0,{from:user3,value:21,gas:30000000}); await instance.buyToken(1,{from:user4,value:22,gas:30000000}); let buyer1 = await instance.testTokenIdToOwner.call(0); let buyer2 = await instance.testTokenIdToOwner.call(1);     //查看購買后的擁有者是誰來核實購買成功進行 console.log(buyer1); console.log(buyer2); console.log("check the sell after buying"); console.log(await instance.tokenIdToSell.call(0)); console.log(await instance.tokenIdToSell.call(1)); assert.equal(buyer1,user3,"buying 0 is failed"); assert.equal(buyer2,user4,"buying 1 is failed"); });    //查看用戶臨時賬戶中此時有多少積蓄 it("check the balance",async function(){ let user1Balance = await instance.pendingDrawalOfUser.call(user1); let user2Balance = await instance.pendingDrawalOfUser.call(user2); console.log(user1Balance); console.log(user2Balance); assert.equal(user1Balance,21,"user1 balance number is not right"); assert.equal(user2Balance,22,"user1 balance number is not right"); });   //然后將臨時賬戶中的錢轉到錢包中 it("withdrawl the balance",async function(){ console.log(await instance.pendingDrawalOfUser.call(user1)); console.log(await instance.pendingDrawalOfUser.call(user2)); await instance.withdrawl({from:user1,gas:30000000}); await instance.withdrawl({from:user2,gas:30000000}); console.log(await instance.pendingDrawalOfUser.call(user1)); console.log(await instance.pendingDrawalOfUser.call(user2)); }); }); 結果是: 用戶deMBP:testToken 用戶$ mocha test-mocha.js in out 0x3455f15cc11f2e77c055f931a6c918ccc7c18fd8 testToken Test 0x86757c9bdea10815e7d75a1577b6d9d2825dae0a check tokenNumber BigNumber { s: 1, e: 1, c: [ 50 ] } nextTokenId is :5
//生成的token的屬性 [ BigNumber { s: 1, e: 0, c: [ 0 ] }, '0x0000000100000000000000000000000000000000000000000000000000000000', '0x3455f15cc11f2e77c055f931a6c918ccc7c18fd8', BigNumber { s: 1, e: 1, c: [ 11 ] } ] [ BigNumber { s: 1, e: 0, c: [ 1 ] }, '0x0000000200000000000000000000000000000000000000000000000000000000', '0x7ddad6a67544efb0c51808c77009a7b98cc81630', BigNumber { s: 1, e: 1, c: [ 12 ] } ] [ BigNumber { s: 1, e: 0, c: [ 2 ] }, '0x0000000300000000000000000000000000000000000000000000000000000000', '0xe9478ebcf4c755ad945a351261c8fa046672963b', BigNumber { s: 1, e: 1, c: [ 13 ] } ] [ BigNumber { s: 1, e: 0, c: [ 3 ] }, '0x0000000400000000000000000000000000000000000000000000000000000000', '0x920f422b761976972a9eadbec1f5341a9747ea6a', BigNumber { s: 1, e: 1, c: [ 14 ] } ] [ BigNumber { s: 1, e: 0, c: [ 4 ] }, '0x0000000500000000000000000000000000000000000000000000000000000000', '0xa17a7fa74a7dd57dff005b45234292e7daaf150c', BigNumber { s: 1, e: 1, c: [ 15 ] } ] ✓ contract begin (1541ms)
// [
true, '0x0000000100000000000000000000000000000000000000000000000000000000', BigNumber { s: 1, e: 0, c: [ 0 ] }, '0x3455f15cc11f2e77c055f931a6c918ccc7c18fd8', BigNumber { s: 1, e: 1, c: [ 21 ] } ] [ true, '0x0000000200000000000000000000000000000000000000000000000000000000', BigNumber { s: 1, e: 0, c: [ 1 ] }, '0x7ddad6a67544efb0c51808c77009a7b98cc81630', BigNumber { s: 1, e: 1, c: [ 22 ] } ] ✓ sell token (663ms) 0x3455f15cc11f2e77c055f931a6c918ccc7c18fd8 0x7ddad6a67544efb0c51808c77009a7b98cc81630 0xe9478ebcf4c755ad945a351261c8fa046672963b 0x920f422b761976972a9eadbec1f5341a9747ea6a check the sell after buying [ false, '0x0000000100000000000000000000000000000000000000000000000000000000', BigNumber { s: 1, e: 0, c: [ 0 ] }, '0x0000000000000000000000000000000000000000', BigNumber { s: 1, e: 0, c: [ 0 ] } ] [ false, '0x0000000200000000000000000000000000000000000000000000000000000000', BigNumber { s: 1, e: 0, c: [ 1 ] }, '0x0000000000000000000000000000000000000000', BigNumber { s: 1, e: 0, c: [ 0 ] } ] ✓ buy token (954ms) BigNumber { s: 1, e: 1, c: [ 21 ] } BigNumber { s: 1, e: 1, c: [ 22 ] } ✓ check the balance (206ms) BigNumber { s: 1, e: 1, c: [ 21 ] } BigNumber { s: 1, e: 1, c: [ 22 ] } BigNumber { s: 1, e: 0, c: [ 0 ] } BigNumber { s: 1, e: 0, c: [ 0 ] } ✓ withdrawl the balance (631ms) 5 passing (4s)

 注意:在這里看好像這個例子也能夠順序執行,但是后面發現上面例子的所以it應該合成一個it來寫,不然順序是不一定能保證的,因為it測試用例在運行時是同步運行的,但是我這里的測試用例其實是有希望它按照順序來運行,所以改為:

describe("testToken Test",function(){


    it("contract begin",async function(){

        let num = propertyValues.length;
        // instance = await testToken.deployed(50);

        console.log(instance.address);
        console.log('check tokenNumber');
        console.log(await instance.tokenNumber.call());
        debug("create token");
     //首先先創建5個token
        for(let i=0; i<num; i++){
            await instance.create(propertyValues[i],prices[i],{from:users[i],value:prices[i],gas:30000000});
        }

        debug("display token");
     //然后查看生成的token的屬性
        let nextTokenId = await instance.nextTokenToCreate.call();
        console.log("nextTokenId is :"+ nextTokenId);

        if(parseInt(nextTokenId) != 5){
            console.log("initial token failed");
        }else{
            for(let i =0; i<num; i++){
                console.log(await instance.propertyOfToken.call(i));
            }

        }

        //然后sell token
        await instance.sellToken(0,21,{from:user1,gas:30000000});
        await instance.sellToken(1,22,{from:user2,gas:30000000});

     //查看是否成功sell
        console.log(await instance.tokenIdToSell.call(0));
        console.log(await instance.tokenIdToSell.call(1));

        //其他用戶對sell的token進行購買
     //查看購買前token的擁有者是誰
        console.log(instance.testTokenIdToOwner.call(0));
        console.log(instance.testTokenIdToOwner.call(1));

        await instance.buyToken(0,{from:user3,value:21,gas:30000000});
        await instance.buyToken(1,{from:user4,value:22,gas:30000000});

        let buyer1 = await instance.testTokenIdToOwner.call(0);
        let buyer2 = await instance.testTokenIdToOwner.call(1);
    //查看購買后的擁有者是誰來核實購買成功進行
        console.log(buyer1);
        console.log(buyer2);

        console.log("check the sell after buying");
        console.log(await instance.tokenIdToSell.call(0));
        console.log(await instance.tokenIdToSell.call(1));

        assert.equal(buyer1,user3,"buying 0 is failed");
        assert.equal(buyer2,user4,"buying 1 is failed");

       //查看用戶臨時賬戶中此時有多少積蓄
        let user1Balance = await instance.pendingDrawalOfUser.call(user1);
        let user2Balance = await instance.pendingDrawalOfUser.call(user2);

        console.log(user1Balance);
        console.log(user2Balance);

        assert.equal(user1Balance,21,"user1 balance number is not right");
        assert.equal(user2Balance,22,"user1 balance number is not right");

     //然后將臨時賬戶中的錢轉到錢包中
        console.log(await instance.pendingDrawalOfUser.call(user1));
        console.log(await instance.pendingDrawalOfUser.call(user2));

        await instance.withdrawl({from:user1,gas:30000000});
        await instance.withdrawl({from:user2,gas:30000000});

        console.log(await instance.pendingDrawalOfUser.call(user1));
        console.log(await instance.pendingDrawalOfUser.call(user2));
    });  

});

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM