mocha测试框架-truffle

https://mochajs.org/
学习网址:
https://www.jianshu.com/p/9c78548caffa
https://www.jb51.net/article/106463.htm
在truffle框架的简单使用中,咱们了解到它的测试模块是包装了mocha测试框架的,在这里咱们选择cryptopunks的truffle例子来相应讲解:javascript

https://github.com/larvalabs/cryptopunkshtml

 

为何要使用mocha这个测试模块:前端

当咱们在开发,咱们每每会有如下的问题:java

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

需求和开发脱节

当一份需求来了, 开发人员每每不能百分百的理解需求的内容(抛弃产品本身变动需求的可能性。。),这每每会让开发人员开发出的功能会有跟需求有所差异,这会带来额外的工做量git

开发和测试脱节

什么是开发和测试脱节,说的是,当开发人员按照本身的想法开发完了一个需求。而后测试人员也按照本身的想法去测试这个需求,而后因为双方的分歧,致使测试认为开发有bug,开发认为测试是sb.github

那么如何解决上面的问题呢?web

答案就是 选择一种软件敏捷开发模式npm

敏捷开发模式

目前比较流行的开发模式有两种: TDD 和 BDDjson

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));
    });  

});
相关文章
相关标签/搜索