Sandbox Testing
In the previous section, we went through the contract's code, analyzing how it worked. Now, we need to test it and make sure it works as expected! For contracts, there are two types of testing you can do: unit testing and sandbox testing.
Here, we will focus on sandbox testing, as it enables one to deploy the contract in a realistic environment, allowing us to create multiple accounts and interact with the contract as if it was deployed on the blockchain.
Unit tests are built into the language and are used to test the contract functions individually. These tests work well when little context is required. However, they cannot test chain interactions - like sending accounts $NEAR tokens - since they need to be processed by the network.
Account Creation
The first thing our test does is to create multiple accounts with 10 $NEAR tokens each and deploy the contract to one of them.
- 🌐 JavaScript
- 🦀 Rust
Loading...
To deploy the contract, we pass the path to the compiled WASM contract as an argument to the test in package.json
. Indeed, when executing npm run test
, the command will first compile the contract and then run the tests.
Loading...
Notice that the sandbox compiles the code itself, so we do not need to pre-compile the contract before running the tests.
Contract Initialization
To initialize, the contract's account calls itself, invoking the init
function with an end_time
set to 60 seconds in the future.
- 🌐 JavaScript
- 🦀 Rust
Loading...
The contract measures time in nanoseconds, for which we need to multiply the result of Date.now()
(expressed in milliseconds) by 10^6
Loading...
The contract measures time in nanoseconds, for which we need to multiply the result of Utc::now().timestamp()
(expressed in seconds) by 10^9
Notice that the time is passed as a String
to the contract, this is because smart contracts cannot receive numbers larger than 52 bits
and we want to pass a unix timestamp
in nanoseconds
Bidding
Now that the contract is deployed and initialized, we can start bidding and checking if the contract behaves as expected.
We first make alice
place a bid of 1 NEAR, and check that the contract correctly registers the bid. Then, we have bob
place a bid of 2 NEAR, and check that the highest bid is updated, and that alice
gets her NEAR refunded.
- 🌐 JavaScript
- 🦀 Rust
Loading...
Loading...
Checking the balance
It is important to notice how we check if alice
was refunded. We query her balance after her first bid, and then check if it has increased by 1 NEAR after bob
makes his bid.
You might be tempted to check if alice
's balance is exactly 10 NEAR after she gets refunded, but alice
balance cannot be 10 NEAR anymore, because some $NEAR was consumed as gas
fees when alice
called bid
.
Testing invalid calls
When testing we should also check that the contract does not allow invalid calls. The next part checks that the contract doesn't allow for bids with fewer $NEAR tokens than the previous to be made.
- 🌐 JavaScript
- 🦀 Rust
Loading...
Loading...
Fast Forwarding Time
The sandbox allows us to fast-forward time, which is useful for testing the contract when the auction is over. The test advances 200 blocks in order to pass a minute, and thus allowing the auction to be claimed.
After which the auction can now be claimed. Once claimed the test checks that the auctioneer has received the correct amount of $NEAR tokens.
- 🌐 JavaScript
- 🦀 Rust
Loading...
Loading...
If you review the tests in full you'll see that we also test other invalid calls such as the auctioneer trying to claim the auction before it is over and a user attempting to bid once the auction is over.