Testing the Factory Contract
Testing factory contracts requires verifying both management functions and the deployment process. We'll use near-workspaces for integration testing.
Test Setup
Create tests/workspaces.rs:
Loading...
Global contracts require nearcore 2.7.0 or later. The sandbox_with_version("2.7.0") ensures we're testing with the correct runtime.
Testing Management Functions
Test that the factory correctly stores and updates configuration:
Loading...
Verify Default Configuration
After deployment, check the default global contract reference:
Loading...
Update to Hash-Based Reference
Test switching to a code hash reference:
Loading...
Verify the Update
Confirm the new configuration is stored:
Loading...
Update to Account-Based Reference
Test switching to an account reference:
Loading...
Verify Minimum Deposit
Check the minimum deposit configuration:
Loading...
Testing Edge Cases
Test error conditions and invalid inputs:
Loading...
This test verifies that using a non-existent global contract hash fails appropriately.
Running Tests
Execute all tests:
# Run all tests
cargo test
# Run only integration tests
cargo test --test workspaces
# Run with output
cargo test -- --nocapture
Unit Tests
You can also add unit tests directly in your contract modules:
#[cfg(test)]
mod tests {
use super::*;
use near_sdk::test_utils::{accounts, VMContextBuilder};
use near_sdk::testing_env;
#[test]
fn test_default_config() {
let context = VMContextBuilder::new()
.current_account_id(accounts(0))
.build();
testing_env!(context);
let contract = GlobalFactoryContract::default();
let expected = GlobalContractId::AccountId(
"ft.globals.primitives.testnet".parse().unwrap()
);
assert_eq!(contract.global_contract_id, expected);
assert_eq!(
contract.min_deposit_amount,
NearToken::from_millinear(200)
);
}
#[test]
#[should_panic(expected = "Attach at least")]
fn test_insufficient_deposit() {
let mut context = VMContextBuilder::new()
.current_account_id(accounts(0))
.attached_deposit(NearToken::from_millinear(100))
.build();
testing_env!(context);
let mut contract = GlobalFactoryContract::default();
contract.deploy("sub".to_string());
}
}
Testing Deployment (Manual)
While near-workspaces doesn't yet support deploying global contracts in tests, you can manually test deployment:
1. Deploy Factory
cargo near deploy <factory-account>
2. Deploy a Sub-Account
near contract call-function as-transaction <factory-account> deploy \
json-args '{"name": "test"}' \
prepaid-gas '100.0 Tgas' \
attached-deposit '0.2 NEAR' \
sign-as <your-account> \
network-config testnet \
sign-with-keychain send
3. Verify Sub-Account Creation
near account view-account-summary test.<factory-account> \
network-config testnet
4. Initialize the Contract
near contract call-function as-transaction test.<factory-account> \
new_default_meta \
json-args '{
"owner_id": "<your-account>",
"total_supply": "1000000000000000000000000"
}' \
prepaid-gas '100.0 Tgas' \
attached-deposit '0 NEAR' \
sign-as <your-account> \
network-config testnet \
sign-with-keychain send
5. Test the Deployed Contract
near contract call-function as-read-only test.<factory-account> \
ft_metadata \
json-args {} \
network-config testnet now
Continuous Integration
Add GitHub Actions for automated testing:
name: Test Factory Contract
on: push
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Rust
uses: actions-rs/toolchain@v1
with:
toolchain: stable
- name: Install cargo-near
run: cargo install --locked cargo-near
- name: Run tests
run: cargo test
Test Coverage
Ensure comprehensive coverage:
- ✅ Default configuration on deployment
- ✅ Updating global contract reference (both types)
- ✅ Updating minimum deposit
- ✅ Querying configuration
- ✅ Invalid global contract hash handling
- ✅ Insufficient deposit handling
- ✅ Invalid sub-account names
- ✅ Access control (private methods)
Debugging Tips
When tests fail:
- Check runtime version: Global contracts need nearcore 2.7.0+
- Verify deposits: Ensure attached deposits meet minimum requirements
- Validate account names: Sub-account names must be valid NEAR account IDs
- Review logs: Use
env::log_strin your contract for debugging - Test incrementally: Start with simple cases and add complexity
Summary
You've learned how to:
- Set up a factory contract project with global contracts support
- Implement the deploy method to create sub-accounts with deployed contracts
- Manage factory configuration and global contract references
- Test the factory with both unit and integration tests
This factory pattern enables efficient, scalable contract deployment across the NEAR ecosystem!
Before deploying to mainnet:
- Thoroughly test with realistic scenarios
- Implement proper access control
- Consider upgrade paths for the factory itself
- Monitor gas costs and optimize where possible
- Document the deployment and initialization process for users