Solidity
測試智能合約時的問題
我正在使用solidity進行智能合約開發,我編寫了下面的智能合約,我對第一個函式addCandidate()的Chai和Mocha測試有一些問題
//SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.5.0 <0.9.0; contract VotingContract{ address public moderator; struct Candidate { uint256 id; string name; uint256 voteCount; } struct Voter { string name; mapping(address => bool) hasVoted; } mapping(address => Voter) public votes; mapping(uint256 => Candidate) public candidateLookup; //candidates will be identified with an unique ID uint256 public candidateCount; //Will be used to track the number of candidates enum State {beforeStart, running, halted} State public electionState; event AddedCandidate(string _name); event Voted( uint256 id, string _name); constructor () { moderator = msg.sender; electionState = State.beforeStart; candidateCount = 0; //Not really necesary to initalize to zero as per solidity documentation -> A variable which is declared will have an initial default value whose byte-representation is all zeros. The “default values” of variables are the typical “zero-state” of whatever the type is. For example, the default value for a bool is false. The default value for the uint or int types is 0 } modifier onlyModerator{ require(msg.sender == moderator, 'Only the moderator of the election can use this function'); _; } modifier votingInProcess { require(electionState == State.running, 'The election is not active at this moment'); _; } function addCandidate(string memory _name) public onlyModerator returns(bool){ Candidate storage newCandidate = candidateLookup[candidateCount]; newCandidate.id = candidateCount; newCandidate.name = _name; newCandidate.voteCount = 0; candidateCount++; emit AddedCandidate(_name); return true; } function getCandidate(uint256 _id) public view returns(uint256, string memory){ string memory name = candidateLookup[_id].name; uint256 voteCount = candidateLookup[_id].voteCount; return (voteCount, name); } function getCandidates() external view returns(string[] memory, uint256[] memory){ string [] memory names = new string[](candidateCount); uint256[] memory voteCounts = new uint[](candidateCount); for (uint256 i = 0; i < candidateCount; i++) { names[i] = candidateLookup[i].name; voteCounts[i] = candidateLookup[i].voteCount; } return (names, voteCounts); } function startVoting() external onlyModerator { electionState = State.running; } function haltVoting() external onlyModerator { electionState = State.halted; } function vote(uint256 _id, string memory _name) public votingInProcess returns (bool){ Voter storage newVoter = votes[msg.sender]; require(_id >= 0 && _id <= candidateCount, 'There is no candidate with the specified ID'); require(newVoter.hasVoted[msg.sender] == false, 'You can only vote one time!'); candidateLookup[_id].voteCount++; newVoter.name = _name; newVoter.hasVoted[msg.sender] = true; emit Voted(_id, _name); return true; } }
這是我到目前為止所做的測試
//getting the contract json representation const VotingContract = artifacts.require('./VotingContract'); const BN = web3.utils.BN; let instance; let accounts; let owner; contract('VotingContract', async(accs) => { accounts = accs; moderator = accounts[0]; }) it('Can add a candidate', async() => { let instance = await VotingContract.deployed(); let id = 0; let newCandidateName = 'Candidate1' await instance.addCandidate(newCandidateName, {from: moderator}); let request = await instance.candidateLookup.call(id) assert.equal(request, newCandidateName) });
但它失敗了,這就是我收到的
1) Can add a candidate 0 passing (489ms) 1 failing 1) Can add a candidate: AssertionError: expected { Object (0, 1, ...) } to equal 'Candidate1' at Context.<anonymous> (test\VotingContract.test.js:21:12) at processTicksAndRejections (internal/process/task_queues.js:93:5)
我不明白 { Object (0, 1, …) } 來自哪裡,
任何人都可以指出我正確的方向嗎?這是什麼?我應該閱讀哪些文件?任何關於我開發的智能合約的額外回饋將不勝感激!
這
candidateLookup
是一個 uint 到候選(結構)而不是字元串(candidateName)的映射。所以訪問candidateLookup
總是會返回一個結構。你可以試試
assert.equal(request[1], newCandidateName)
因為根據您的結構定義;
request[0]: id, request[1]: name, request[2]: voteCount