5

My contract has an expiration date that I'd like to unit test but I don't know how to go about doing that. If I could mock the time of the contract that would be dope. Google search provided no information though.

4 Answers 4

3

As a general testing method, you can create another, debugging-only, contract descending from your production contract. This second contract can have methods to do anything--for example, to set the expiration date to now.

If you want to mess with time specifically, TestRPC has an RPC method to fast forward time. Be warned, you'll have to integrate it into your testing harness somehow, since web3 does not come with it.

2
5

This is a fairly old question but I thought I would add this for those looking:

You can utilize the evm_increaseTime method that you get with both hardhat and ganache.

Here's an example with ethers

await ethers.provider.send("evm_increaseTime", [10]) // add 10 seconds
await ethers.provider.send("evm_mine", []) // force mine the next block

And here with web3

web3.currentProvider.send({jsonrpc: "2.0", method: "evm_increaseTime", params: [10], id: 0})
web3.currentProvider.send({jsonrpc: "2.0", method: "evm_mine", params: [], id: 0})
1
  • 1
    Bro you are a life saver!
    – Adil Nehal
    Feb 2, 2022 at 11:24
4

I've been making my contracts descend from a simple contract that has a currTime() function and a testing boolean. If I set testing to true, currTime() returns a fake time, which I can manipulate with functions like addDays(uint days). If testing is false, then currTime() just returns block.timestamp. Every place where I'd check the timestamp, I call currTime() instead.

3
  • Thanks for the tip, this is what I needed to get my tests working. One more question though, when you deploy your contract do you remove the contract that you use to manipulate the current time?
    – The Nomad
    Aug 28, 2017 at 3:46
  • 1
    That's tricky. You don't really want to change the tested code when you deploy, but it's kinda nasty leaving it in, too. I guess you just have to decide what's best for your particular contract. Aug 29, 2017 at 1:50
  • Good call. I actually just rewrote all my tests to Mocha tests as it's easier to manipulate time that way.
    – The Nomad
    Aug 29, 2017 at 2:24
1

There is a library in Dapphub: https://github.com/dapphub/ds-warp

A simple mixin for controlling time.

Return the current time with era(). Advance time with warp.

warp(0) to lock the current time to the blocktime.

contract DSWarpTest is DSTest {
    DSWarp warp;

    function setUp() {
        warp = new DSWarp();
    }
    function testInit() {
        assertEq(warp.era(), now);
    }
    function testWarp() {
        var tic = now;
        warp.warp(1);
        assertEq(warp.era(), tic + 1);
    }
    function testWarpLock() {
        warp.warp(0);
        assertEq(warp.era(), now);
    }
    function testFailAfterWarpLock() {
        warp.warp(0);
        warp.warp(1);
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.