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.
// 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);
}
}// 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);
}
}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.