Skip to content
This repository has been archived by the owner on Aug 21, 2024. It is now read-only.

Commit

Permalink
Update the tutorial for testing (#91)
Browse files Browse the repository at this point in the history
  • Loading branch information
leighmcculloch authored Aug 30, 2022
1 parent 85363a8 commit 32210fb
Showing 1 changed file with 32 additions and 15 deletions.
47 changes: 32 additions & 15 deletions docs/tutorials/testing.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,14 @@ Contract](write-a-contract.mdx), a simple test will look like this.

```rust
#![no_std]
use soroban_sdk::{contractimpl, vec, Env, Symbol, Vec};
use soroban_sdk::{contractimpl, symbol, vec, Env, Symbol, Vec};

pub struct Contract;

#[contractimpl(export_if = "export")]
#[contractimpl]
impl Contract {
pub fn hello(env: Env, to: Symbol) -> Vec<Symbol> {
const GREETING: Symbol = Symbol::from_str("Hello");
vec![&env, GREETING, to]
vec![&env, symbol!("Hello"), to]
}
}
```
Expand All @@ -36,26 +35,38 @@ impl Contract {
```rust
#![cfg(test)]

use super::{Contract, hello};
use soroban_sdk::{vec, Env, FixedBinary};
use super::{Contract, ContractClient};
use soroban_sdk::{symbol, vec, BytesN, Env};

#[test]
fn test() {
let env = Env::default();
let contract_id = FixedBinary::from_array(&env, [0; 32]);
let contract_id = BytesN::from_array(&env, &[0; 32]);
env.register_contract(&contract_id, Contract);
let client = ContractClient::new(&env, &contract_id);

let words = hello::invoke(&env, &contract_id, &Symbol::from_str("Dev"));
let words = client.hello(&symbol!("Dev"));
assert_eq!(
words,
vec![&env, Symbol::from_str("Hello"), Symbol::from_str("Dev"),]
vec![&env, symbol!("Hello"), symbol!("Dev"),]
);
}
```


</TabItem>
</Tabs>

:::info
The above example is a [Rust unit test] that lives inside the `src/` directory.
Note that if you place the test in the `tests/` directory it becomes a [Rust
integration test] with the test being compiled separately. Integration tests
require `#![cfg(feature = "testutils")]` at the top of the file and to be run
with the `testutils` feature enabled, e.g. `cargo test --features testutils`, to
enable the generated Soroban test utilities.
:::


In any test the first thing that is always required is an `Env`, which is the
Soroban environment that the contract will run inside of.

Expand All @@ -69,23 +80,26 @@ if the test will deploy the contract multiple times, or deploy multiple
contracts, each should use their own IDs.

```rust
let contract_id = FixedBinary::from_array(&env, [0; 32]);
env.register_contract(&contract_id, HelloContract);
let contract_id = BytesN::from_array(&env, &[0; 32]);
env.register_contract(&contract_id, Contract);
```

All public functions within an `impl` block that is annotated with the
`#[contractimpl]` attribute have an `invoke` function generated, that can be
used to invoke the contract function within the environment.
`#[contractimpl]` attribute have a corresponding function generated in a
generated client type. The client type will be named the same as the contract
type with `Client` appended. For example, in our contract the contract type is
`Contract`, and the client is named `ContractClient`.

```rust
let words = hello::invoke(&env, &contract_id, &Symbol::from_str("SourBun"));
let client = ContractClient::new(&env, &contract_id);
let words = client.hello(&symbol!("Dev"));
```

The values returned by functions can be asserted on:
```rust
assert_eq!(
words,
vec![&env, Symbol::from_str("Hello"), Symbol::from_str("SourBun"),]
vec![&env, symbol!("Hello"), symbol!("Dev"),]
);
```

Expand All @@ -103,3 +117,6 @@ test test::test ... ok
```

Try changing the values in the test to see how it works.

[Rust unit test]: https://doc.rust-lang.org/rust-by-example/testing/unit_testing.html
[Rust integration test]: https://doc.rust-lang.org/rust-by-example/testing/integration_testing.html

0 comments on commit 32210fb

Please sign in to comment.