Unit Testing in Truffle

Sorry no idea where to begin with testing the balances…

I am receiving an error mentioning Error: Truffle is currently using solc 0.5.8, but one or more of your contracts specify "pragma solidity 0.5.12". Please update your truffle config or pragma statement(s).

1 Like

A bit difficult that for the novices …

  let balanceBefore = parseFloat(awaitweb3.eth.getBalance(accounts[0]));
//parseFloat i would of never of got....... Never even heard of it :L.   
await instance.withdrawAll();
  let balanceAfter = parseFloat(await web3.eth.getBalance(accounts[0]));
  assert(balanceBefore < balanceAfter, "Owners balance was not increased after withdrawal");

Hi mate, i had the same issue and you can edit the Compiler in youre truffle.config.js file ;).

2 Likes
const People = artifacts.require("People");
const truffleAssert = require("truffle-assertions");

contract("People", async function(accounts){
    it("shouldn't create a person with age over 150 years", async function(){
        let instance = await People.deployed();
        await truffleAssert.fails(instance.createPerson("Bob", 150, 190, {value: web3.utils.toWei("1", "ether")}), truffleAssert.ErrorType.Revert);
    });
    it("shouldn't create a person without payment", async function(){
        let instance = await People.deployed();
        await truffleAssert.fails(instance.createPerson("Bob", 37, 190, {value: 1000}), truffleAssert.ErrorType.Revert);
    });
    it("should set senior status correctly", async function(){
        let instance = await People.deployed();
        await instance.createPerson("Bob", 65, 190, {value: web3.utils.toWei("1", "ether")});
        let result = await instance.getPerson();
        assert(result.senior === true, "Senior level not set");
    });
    it("should set age correctly", async function() {
        let instance = await People.deployed();
        let result = await instance.getPerson();
        assert(result.age.toNumber() === 65, "Age not set correctly");
    });
    it("Verifies if other account besides the Owner can delete a Person", async function(){
        let instance = await People.deployed();
        await instance.createPerson("Mitnick", 50, 190, {from: accounts[1], value: web3.utils.toWei("1", "ether") });
        await truffleAssert.fails(instance.deletePerson(accounts[1], {from: accounts[1]}), truffleAssert.ErrorType.REVERT);
    });
    it("Verifies if the Owner can delete a Person", async function(){
        let instance = await People.deployed();
        await instance.createPerson("Filipe", 37, 180, {from: accounts[1], value: web3.utils.toWei("1", "ether") });
        await truffleAssert.passes(instance.deletePerson(accounts[1], {from: accounts[1]}));
    });
});
1 Like

Hey @kryptokrymmenos

You can follow this: FAQ - How do change truffle version

:cupid: dani!!!1!!!1 finally!!! thanks a loooooooooooooooooooooooot

2 Likes

Owner Test Assignment:

it(“should only delete by owner”, async function(onlyOwner)
{
let instance = await People.deployed();
assert(msg.sender==onlyOwner,“Only owner can delete”);
})

My best guess before looking at the solution but will definitely improve once I see the solution and grow my knowledge with it.

Hi guys, there you go

const truffleAssert = require('truffle-assertions');
const People = artifacts.require('People');

contract('People', async function(accounts) {
    it('should not create a person with age over 150 years', async function() {
        let instance = await People.deployed();
        await truffleAssert.fails(
            instance.createPerson('Bob', 200, 170, {value: web3.utils.toWei('1', 'ether')}),
            truffleAssert.ErrorType.REVERT
        );
    });

    it('should not create a person without correct amount of payment', async function() {
        let instance = await People.deployed();
        await truffleAssert.fails(
            instance.createPerson('Bob', 50, 170, {value: 1000}), 
            truffleAssert.ErrorType.REVERT
        );
    });

    it('should set senior status correctly', async function() {
        let instance = await People.deployed();
        await instance.createPerson('Bob', 65, 170, {value: web3.utils.toWei('1', 'ether')});
        let person = await instance.getPerson();
        assert.equal(person.senior, true, 'status should be senior if age is equal to or over 65 years old');
    });

    it('should not allow non-owner to delete people', async function() {
        let instance = await People.deployed();
        await instance.createPerson('Bob', 65, 170, {value: web3.utils.toWei('1', 'ether'), from: accounts[1]});            
        await truffleAssert.fails(
            instance.deletePerson(accounts[1], { from: accounts[1] }),
            truffleAssert.REVERT
        );
    });
});

Hi guys,

Here I post my solution. It works.

const truffleAssert = require('truffle-assertions');
const People = artifacts.require('People');

contract('People', async function(accounts) {
    let instance;

    before(async function() {
        instance = await People.deployed();
    });

   ... 

    it('should increase contract balance when create person', async function() {
        instance = await People.new();  // create brand new copy of contract
        await instance.createPerson('Bob', 65, 170, {value: web3.utils.toWei('1', 'ether'), from: accounts[3]});
        let bal = await web3.eth.getBalance(instance.address);
        assert.equal(bal, web3.utils.toWei('1', 'ether'), 'each successful create person will add balance to contract');
    });

    it('should NOT allow non-owner to withdraw balance from contract', async function() {
        await truffleAssert.fails(
            instance.withdrawAll({from: accounts[1]}),
            truffleAssert.REVERT
        );
    });

    it('should only allow owner to withdraw balance from contract', async function() {
        let balBfrWithdraw = await web3.eth.getBalance(accounts[0]);

        await truffleAssert.passes(
            instance.withdrawAll({from: accounts[0]})
        );
        
        let balAftWithdraw = await web3.eth.getBalance(accounts[0]);

        assert(balAftWithdraw > balBfrWithdraw, 'owner account balance should increase in ether');
    });
});
1 Like

Value Assignment Attempt:

it(“should update balance of contract address when person added”, async function()
{
await instance.createPerson(“Lisa”, 35, 160,{from:accounts[1],value:web3.utils.toWei(“1”,“ether”)});
assert(balance===web.eth.getBalance(contract address), “balance not updated”)
});
it(“should update balance of owner address after contract address funds withdrawn”, async function()
{
await instance.createPerson(“Bob”, 35, 160,{from:accounts[1],value:web3.utils.toWei(“1”,“ether”)});
await instance.withdrawAll({from:accounts[0]})
mgs.value+=toTransfer
assert(balance==0, “balance not withdrawn”)
});

@dan-i … anyhow … you got me thinking … why do we need to downgrade Node.js in order for this test to work? what is the incompatibility between node.js and truffle or ganache?? :face_with_monocle: :nerd_face: … I was busy learning how to create a front-end app with react at codeacademy!!!

Here is my answer to the assignment:

  it("person deleted by owner is ok", async function(){
    let instance = await People.deployed();
    await instance.createPerson("javier", 37, 180, {from: accounts[2], value: web3.utils.toWei("1", "ether")});
    await truffleAssert.fails(instance.deletePerson(accounts[2], {from: accounts[2]}), truffleAssert.ErrorType.REVERT);
  });
  it("person not deleted by owner is ok", async function(){
    let instance = await People.deployed();
    await instance.createPerson("javier", 37, 180, {value: web3.utils.toWei("1", "ether")});
    await truffleAssert.reverts(instance.deletePerson(accounts[2], {from: accounts[1]}), "only owner");

sadly, these 2 tests failed :sweat_smile: … I suspect that it has to do with this message that I am getting:

I really struggled with this assignment and my code would not work and at time of posting this I have no idea why.

The confirmation of deletion code works fine but I cannot understand why when I call the deletePerson function with what is clearly address[1], the function completes with address[0] being called as the deletor. I must be missing something.

const People = artifacts.require(“People”);
const truffleAssert = require(“truffle-assertions”);
contract(“People”, async function(accounts){
it(“Should not create person if over 150”, async function(){
let instance = await People.deployed();
await truffleAssert.fails(instance.createPerson(“Bob”, 200, 190, {value: web3.utils.toWei(“1”, “ether”)}), truffleAssert.ErrorType.REVERT);
});
it(“Should not create person if insufficient payment”, async function(){
let instance = await People.deployed();
await truffleAssert.fails(instance.createPerson(“Bob”, 50, 190, {value: 1000}), truffleAssert.ErrorType.REVERT);
});
it(“Should set senior bool if age above 65”, async function(){
let instance = await People.deployed();
console.log("Creator = ", accounts[0]);
await instance.createPerson(“Bob”, 70, 190, {value: web3.utils.toWei(“1”, “ether”), from:accounts[0]});
let result = await instance.getPerson();
assert(result.senior === true, “Senior value not set”);
});
it(“Should set age correctly”, async function(){
let instance = await People.deployed();
let result = await instance.getPerson();
assert(result.age.toNumber() === 70, “Age not set correctly”);
});
it(“Check delete operation only works for owner”, async function(){
let instance = await People.deployed();
console.log("Deletor = ", accounts[1]);
await truffleAssert.fails(instance.deletePerson(accounts[1]), truffleAssert.ErrorType.REVERT);
});
it(“Check delete works for owneroperation only works for owner”, async function(){
let instance = await People.deployed();
let result = await instance.getPerson();
console.log('Age = ’ , result.age.toNumber())
await instance.deletePerson(accounts[0]);
result = await instance.getPerson();
console.log('Age = ’ , result.age.toNumber())
assert(!(result.age.toNumber() === 70), “Person not deleted”);
});
});

Looking back at this I can see the two errors I have made. Firstly I had misunderstood what the onlyOnwer function does. Firstly as I was not using the from parameter then all my deleltePerson calls were being done as account[0]. I was also wrongly assuming that as account[0] I should not be able to call deletePerson(account[1]). Solution now makes sense to me.

Hey @javier_ortiz_mir

You have to downgrade as node as somewhere a bug with truffle.
Because there is nothing we can do about it, we have to downgrade.
Hopefully will be fixed in future releases.

Hey, please post the whole test file.

thanks

Hey @cryptophile

What errors do you get when running your tests?

cheers,
Dani

My first attempt, although it doesn’t seem the Solidity style :blush:

contract('People', async (accounts) => {
  let instance;

  beforeEach(async () => {
    instance = await People.deployed();
  });

  it('should delete a person', async () => {
    await instance.createPerson('Sam4', 30, 170, {value: web3.utils.toWei('2', 'ether')});
    let person = await instance.getPerson();
    assert.equal(person[0], 'Sam4', 'The name should be Sam4.');

    await instance.deletePerson(accounts[0]);
    person = await instance.getPerson();
    assert.equal(person[0], '', 'The name should be an empty string because the person was deleted.');
  });

  it('should allow only contract owners to delete persons', async () => {
    await instance.createPerson('Sam5', 30, 180, {value: web3.utils.toWei('1', 'ether')});
    await instance.deletePerson(accounts[1]);
    let person = await instance.getPerson();
    assert.equal(person[0], 'Sam5', 'Person should not be deleted by anyone other than the owner.')

    await instance.deletePerson(accounts[0]);
    person = await instance.getPerson();
    assert.equal(person[0], '', 'The name should be an empty string because the person was deleted by the contract owner.')
  })
});
1 Like

Hey @Samy

You are indeed writing your tests in Javascript not Solidity :slight_smile:
You will surely get used to JS as you can do really amazing things with it.

If you need help we are here :slight_smile:

Happy learning,
Dani