Tooling

Testing

cargo test runs unit tests against the contract as a plain Rust struct. near-workspaces is the sandbox for cross-contract and gas — like forge fork tests.

Unit tests on NEAR are fast because they call the contract as an ordinary Rust struct — no chain involved. For anything that needs real gas, promises, or a second contract, you spin up a sandbox with near-workspaces.

A unit test
Solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

import "forge-std/Test.sol";
import "../src/Counter.sol";

contract CounterTest is Test {
    function test_Increment() public {
        Counter c = new Counter();
        c.increment();
        c.increment();
        assertEq(c.count(), 2);
    }
}
Rust
// in the same crate as the contract
#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn increments() {
        let mut c = Counter::default();
        c.increment();
        c.increment();
        assert_eq!(c.get_count(), 2);
    }
}
Coming from EVM

forge test ↔ cargo test. Unit tests instantiate the contract struct directly and call methods — no deployment. assertEq ↔ assert_eq!.

Need a caller, an attached deposit, or block context? Build it with VMContextBuilder and set it before the call — the analog of Foundry’s vm.prank / vm.deal.

For real cross-contract calls, promises, callbacks, and gas accounting, use near-workspaces: it launches a sandbox node and deploys your compiled wasm — the equivalent of forge’s fork / integration tests.