let instance;
let createPersonFee = 1000;
it("should increase the balance of the contract when a person is created", async function() {
let instance = await People.new();
let balance = await web3.eth.getBalance(instance.address);
await instance.createPerson("Good Juan", 22, 140, {
value: createPersonFee,
from: accounts[0]
});
balance = await web3.eth.getBalance(instance.address);
await assert.equal(balance, createPersonFee, "The createPerson function did not increase contract balance")
});
it("should not let someone other than the owner to withdraw the balance", async function() {
await truffleAssert.fails(
instance.withdrawAll({
from: accounts[3]
})
)
});
it("should let owner to widthdrawAll from contract", async function() {
await truffleAssert.passes(
instance.withdrawAll({
from: accounts[0]
})
)
});
Also created a test that considers gas prices and calculates gasPrice, this was a nice excercise to understand how to calculate gasCost and gasPrice
it("should increase balance after withdraw considering gas price", async function() {
const instance = await People.new();
const originalBalance = parseInt(await web3.eth.getBalance(accounts[0]));
// Creation
const createReceipt = await instance.createPerson("Good Juan", 22, 140, {
value: createPersonFee,
from: accounts[0]
});
// Get gas cost of create
const gasUsedInCreate = createReceipt.receipt.gasUsed;
const txCreate = await web3.eth.getTransaction(createReceipt.tx);
const gasPriceInCreate = txCreate.gasPrice;
// withdrawal
const withdrawReceipt = await instance.withdrawAll()
// Gas cost of withdrawal
const gasUsedInWithdraw = withdrawReceipt.receipt.gasUsed;
const txWithdraw = await web3.eth.getTransaction(withdrawReceipt.tx);
const gasPriceInWithdraw = txWithdraw.gasPrice;
const gasCost = gasPriceInCreate * gasUsedInCreate + gasUsedInWithdraw * gasPriceInWithdraw;
let currentBalance = parseInt(await web3.eth.getBalance(accounts[0]));
assert.equal(originalBalance + createPersonFee - gasCost , currentBalance, "Balance did not increase as expected")
})
deletePerson unit test:
it("should be deleted by owner only", async() =>{
let instance = await People.deployed();
await instance.createPerson("An", 70, 190, {value: web3.utils.toWei("1", "ether")});
let creator1 = await instance.getCreator(0);
await truffleAssert.fails(instance.deletePerson(creator1, {from: accounts[1]}) , truffleAssert.ErrorType.REVERT);
});
Iāve spent more time on this then expectedā¦did not know exactly how and where to utilize accounts arrayā¦ I guess I would need to dig deeper in truffle testing until I start feeling more comfortable with it
it("only owner can delete this contract", async function(){
let instance = await People.deployed();
await instance.createPerson("Marko", 36, 180, {from: accounts[1], value: web3.utils.toWei("1", "ether")});
await truffleAssert.fails(instance.deletePerson(accounts[1], {from: accounts[1]}), truffleAssert.ErrorType.REVERT);
});
Iām not sure about these. The first one passes but I believe its simply because the fakeAddress is not in the creators array therefore it fails simple cause its not in the array. I am not sure how to really test if it lets you delete another persons address with your own address since whenever you call the deletePerson function it gets the msg.sender which is the same as whats used to create the person.
const People = artifacts.require("People"); //imports contract
const truffleAssert = require("truffle-assertions");
contract("People",async function(accounts){
it("should only allow the owner to delete the person created by the owner", async function(){
let instance = await People.deployed();
let fakeAddress = 0x236E8bf1AfE056D762310EC506AE3Eb774E261f6;
await instance.createPerson("bob",55,180,{value:web3.utils.toWei("1","ether")});
await truffleAssert.fails(instance.deletePerson(fakeAddress));
});
it("Creator should be the same as deleter", async function(){
let instance = await People.deployed();
let person = await instance.createPerson("bob",55,180,{value:web3.utils.toWei("1","ether")});
let creator = await instance.getCreator(0);
assert(accounts[0]===creator);
});
});
it("should increse local balance on create person", async () => {
instance = await People.new()
await instance.createPerson("Bob", 65, 190, {
value: web3.utils.toWei("1", "ether")
})
assert(await instance.balance() == web3.utils.toWei("1", "ether"), "Balance does not update properly")
})
it('should have the same balance locally and globally', async () => {
// Create one more person to have extra accuracy
await instance.createPerson("Lisa", 35, 160, {
value: web3.utils.toWei("1", "ether"),
from: accounts[1]
})
assert(await instance.balance() == await web3.eth.getBalance(instance.address), "Local balance mismatch")
})
it("shouldn't allow non owner to withdraw", async () => {
await truffleAssert
.fails(instance.withdrawAll({
from: accounts[1]
}), truffleAssert.ErrorType.REVERT)
})
it("should allow owner to withdraw", async () => {
await truffleAssert
.passes(instance.withdrawAll({
from: accounts[0]
}))
})
it("should have local balance equal to 0 after withdrow", async () => {
assert(await instance.balance() == 0)
})
it("should have global balance equal to 0 after withdrow", async () => {
assert(await await web3.eth.getBalance(instance.address) == 0)
})
Value Assignment:
Iām not sure why but the bottom check always returns and AssertionError: Unspecified AssertionError. I can remove but then the one that worked fine above it will return the same error. Anyone else have the same problem?
Edit: I was also curious how do we call on public state variables? Can it be done from the contract or just by instance? Like you can get the address of the contract this way.
const People = artifacts.require("People");
let peopleAddress = await People.address;
Is it not possible to get the balance on the contract by using this?
let balance = await People.balance();
const People = artifacts.require("People");
const truffleAssert = require("truffle-assertions");
contract("People",async function(accounts){
let instance;
let peopleAddress;
let blockChainStartingBalance;
let blockChainEndBalance;
let instanceEndBalance;
before(async function(){
instance = await People.new();
peopleAddress = await People.address
blockChainStartingBalance = await web3.eth.getBalance(accounts[0])
});
it("should have both Balance on the chain and in the instance of People the same", async function(){
await instance.createPerson("bob",55,255{from:accounts[1],value:web3.utils.toWei("1","ether")});
let chainBalance = await web3.eth.getBalance(peopleAddress);
let instanceBalance = await web3.eth.getBalance(await instance.address);
assert(chainBalance===instanceBalance);
});
it("should let owner remove all of balance",async function(){
await truffleAssert.passes(instance.withdrawAll({from:accounts[0]}));
});
it("should make both balances zero", async function(){
let chainBalance = await web3.eth.getBalance(peopleAddress);
let instanceBalance = await web3.eth.getBalance(await instance.address);
assert(chainBalance==="0"&&instanceBalance==="0");
});
it("the end blance of the owner should be more than the start balance of the owner",async function(){
blockChainEndBalance = await web3.eth.getBalance(accounts[0])
assert(blockChainEndBalance>blockChainStartingBalance)
console.log(blockChainStartingBalance,blockChainEndBalance+ "end and start")
});
//end always gets AssertionError: unspecified AssertionError
it("should let owner remove all of balance",async function(){
await truffleAssert.passes(instance.withdrawAll({from:accounts[0]}));
});
});
const People = artifacts.require("People");
const truffleAssert = require("truffle-assertions");
contract("People", async function(accounts) {
let instance;
beforeEach(async function() {
instance = await People.new();
await instance.createPerson("Bob", 65, 190, {value:web3.utils.toWei("1", "ether")});
});
it ("should increase balance when person added", async function() {
let initialBalance = Number(await instance.balance());
let weiToPay = web3.utils.toWei("1", "ether"); // 1 eth converted to wei
await instance.createPerson("Alice", 62, 180, {value:weiToPay});
let calcBalance = initialBalance + Number(weiToPay);
let finalBalance = Number(await instance.balance());
assert(calcBalance === finalBalance, `Balance incorrect: should be=${calcBalance}, actual=${finalBalance}`);
});
it ("should match balance variable in contract and balance registered with contract address on blockchain", async function(){
let balanceInContract = Number(await instance.balance());
let balanceOnBlockchain = Number(await web3.eth.getBalance(instance.address));
assert(balanceOnBlockchain === balanceInContract,
`Balances don't match: balance in contract=${balanceInContract}, balance registered with contract address on blockchain=${balanceOnBlockchain}`);
});
it ("should allow only owner to withdraw balance", async function() {
await truffleAssert.fails(instance.withdrawAll({from:accounts[1]}), truffleAssert.ErrorType.REVERT);
await truffleAssert.passes(instance.withdrawAll({from:accounts[0]}));
});
it ("should reduce balance variable in contract to zero after withdrawal", async function() {
await instance.withdrawAll({from:accounts[0]});
let balance = Number(await instance.balance());
assert(balance === 0, `Balance after withdrawal is not zero: ${balance}`);
});
it ("should match balance variable in contract and balance registered with contract address on blockchain after withdrawal", async function() {
await instance.withdrawAll({from:accounts[0]});
let balanceInContract = Number(await instance.balance());
let balanceOnBlockchain = Number(await web3.eth.getBalance(instance.address));
assert(balanceOnBlockchain === balanceInContract,
`Balances don't match: balance in contract=${balanceInContract}, balance registered with contract address on blockchain=${balanceOnBlockchain}`);
});
it ("should increase owner's balance after withdrawal", async function() {
let balanceOwnerInitial = Number(await web3.eth.getBalance(accounts[0]));
await instance.withdrawAll({from:accounts[0]});
let balanceOwnerFinal = Number(await web3.eth.getBalance(accounts[0]));
assert(balanceOwnerInitial < balanceOwnerFinal,
`Owner's balance has not increased: owner initial balance=${balanceOwnerInitial}, owner final balance=${balanceOwnerFinal}`);
});
})
@mikekai
it will be very nice, if you could elaborate your question a bit more or even share a GitHub link
Everything has worked for me in Ganache / Truffle until I tried to create and run the tests. It shows the errors in the following screen that I canāt figure out. I have tried calling it also with the full code from Filipās github but Iām getting the same error. Calling messages etc. from before worked well in my PowerShell. Does anyone know how to fix it?
it("should not allow non-owner to delete person", async function(){
let instance=await People.deployed();
await instance.createPerson("Eduarda",26,160, {from: accounts[2], value: web3.utils.toWei("1","ether")});
await truffleAssert.fails(instance.deletePerson(accounts[2],{from:accounts[2]},truffleAssert.ErrorType.REVERT));
});
it("should let owner delete person", async function(){
let instance=await People.deployed();
await truffleAssert.passes(instance.deletePerson(accounts[2], {from:accounts[0]}));
});
First test is to see of non-owner canāt delete. Second test is to see if owner can delete. Same person created in first step is used.
@Ondrej.S
Thanks for reaching out!
The issue is mostly with Node.js version
Let me know which version you are using?
it("should delete Bob", async function(){
let instance = await People.deployed();
await instance.deletePerson(accounts[0]);
});
it("shouldnt delete Bob because you are not contract owner", async function(){
let instance = await People.deployed();
await truffleAssert.fails(instance.deletePerson(accounts[0], {from: accounts[1]}),
truffleAssert.ErrorType.REVERT);
});
Thank you for reaching out! I was using 6.14.4 version. Iāve just updated it to the latest version and it still show the same error. Any suggestions?
hi all, just wondering why we need to use instance.balance()
and not instance.balance
, because balance
isnāt a function, itās a variable of type uint
. Can anyone explain?
check the node version
node -v
6.14.4 is the npm version
@doctormartin67
Thanks for reaching out!
Can you elaborate more on your question?
We use .call()
to access variable using web3.
Are you sure balance
is not a function?
@Taha
in this test:
it("should reset to zero after withdrawal", async function(){
let instance = await People.new();
await instance.createPerson("Bob", 65, 190, {from: accounts[1], value: web3.utils.toWei("1", "ether")});
await instance.withdrawAll({from: accounts[0]});
var balance = parseFloat(await instance.balance());
var realBalance = await web3.eth.getBalance(instance.address);
assert(balance == web3.utils.toWei("0", "ether") && balance == realBalance, "balance isnt the same as the real balance and/or balance doesnt equal 0");
});
you see in the 5th line var balance = parseFloat(await instance.balance());
. what is balance()
referring to here? because in the contract People, balance isnt a function.
Edit: I think I figured it out. Balance is a public variable, is it true that solidity automatically creates a getter function for public variables? If so then I understand.
It was v12.16.3, now itās 14.5.0 after update and yet I get the same error as in screen when running the test. Everything else works fine.