Changing VMContext attributes during tests
Asked Answered
I

2

5

I want to write tests that require the ability to change predecessor accounts mid-test. But I couldn't find a way to change the VMContext dynamically.

fn get_context(value: u128) -> VMContext {
        VMContext {
            current_account_id: "alice.near".to_string(),
            signer_account_id: "bob.near".to_string(),
            signer_account_pk: vec![0, 1, 2],
            predecessor_account_id: "carol.near".to_string(),
            input: vec![],
            block_index: 0,
            account_balance: 0,
            is_view: false,
            storage_usage: 0,
            block_timestamp: 123789,
            attached_deposit: value,
            prepaid_gas: 10u64.pow(9),
            random_seed: vec![0, 1, 2],
            output_data_receivers: vec![],
        }
    }

    #[test]
    fn test_market_creation() {
        let mut context = get_context(500000000);
        let config = Config::default();
        testing_env!(context, config);
        let mut contract = MyContract::default();
        contract.do_something(); // Fire method with "carol.near" as predecessor
        // Switch account to "bob.near"
        contract.do_something(); // Fire method with "bob.near" as predecessor
    }
Interrupt answered 20/11, 2019 at 14:31 Comment(0)
C
6

When you call ‘testing_env!‘ again with a new context within the same test, it will keep the old storage, but use the new context.

Take a look at tests for fungible token example https://github.com/nearprotocol/near-bindgen/blob/75a62c7c1fd46feda614c4e7776d02eeea054ef8/examples/fun-token/src/lib.rs#L395

Chirr answered 20/11, 2019 at 15:14 Comment(0)
L
4

Fields in VMContext are public. It should be possible to change any of its fields:

#[test]
    fn test_market_creation() {
        let mut context = get_context(500000000);
        context.predecessor_account_id = "carol.near".to_string();
        let config = Config::default();
        testing_env!(context, config);
        let mut contract = MyContract::default();
        contract.do_something(); // Fire method with "carol.near" as predecessor
        // Switch account to "bob.near"
        contract.do_something(); // Fire method with "bob.near" as predecessor
    }
Lucretialucretius answered 20/11, 2019 at 15:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.