# Unit Testing Transaction

The parsed transaction can be used for inspection, primarily in the scenario of unit testing the transaction-building process.

To obtain the `TxTester`:

```rust
let mut tx_tester = tx_parser.to_tester();
```

### Interpret result

After adding checks, the success case:

```rust
assert!(tx_tester.success()); // passing
 
let error_msg = tx_tester.errors();
println!(error_msg) // "No errors"
```

If case there is an error, there would be tracing about where it fails the checks:

```rust
println!("Errors: {:?}", tx_tester.errors());

// For example, failing at finding inline datum at outputs
Errors: "[Error - outputs_inline_datum_exist]: No outputs with inline datum matching: d905039fd8799fd8799f5041bfc7325343428683bbd0b94a4da41cd8799f581ce1197f10e85bc4a3a812e34e22339e1df56b7fb6386a9510d7a304ffffd8799f581c7c87b6b5a0963af3eadb107da2ac4e1d34747a4df363858b649aa845ffffffa140a1401a00989680ff"
```

### Testing inputs

Testing inputs starts with locating the inputs you want to test. The filtering will not reset until the filtering methods are called again.

* `all_inputs` - not apply filters
* `inputs_at` - filtering inputs with address
* `inputs_with` - filtering inputs with token
* `inputs_with_policy` - filtering inputs with policy id
* `inputs_at_with` - filtering inputs with address and token
* `inputs_at_with_policy` - filtering inputs with address and policy id

Then it comes with the checks:

* `inputs_value` - check the aggregated value of filtered inputs
* `inputs_inline_datum_exist` - check whether any of the filtered inputs with the inline datum

Example

```rust
tx_tester
    .inputs_at("addr_test1qrs3jlcsapdufgagzt35ug3nncwl26mlkcux49gs673sflmrjfm6y2eu7del3pprckzt4jaal9s7w9gq5kguqs5pf6fq542mmq")
    .inputs_value(Value::from_asset(&Asset::new_from_str("lovelace", "10000000000")))
    .inputs_inline_datum_exist(WData::JSON(output_datum.to_string()).to_cbor().unwrap().as_str())
```

### Testing outputs

Testing outputs starts with locating the outputs you want to test. The filtering will not reset until the filtering methods are called again.

* `all_outputs` - not apply filters
* `outputs_at` - filtering outputs with address
* `outputs_with` - filtering outputs with token
* `outputs_with_policy` - filtering outputs with policy id
* `outputs_at_with` - filtering outputs with address and token
* `outputs_at_with_policy` - filtering outputs with address and policy id

Then it comes with the checks:

* `outputs_value` - check the aggregated value of filtered outputs
* `outputs_inline_datum_exist` - check whether any of the filtered outputs with the inline datum

Example

```rust
tx_tester
    .outputs_value(Value::from_asset(&Asset::new_from_str("lovelace", "8000000")))
    .outputs_at_with("addr_test1wpgxy3dc6yzzs4y5n8k0e5zrt4dqhx364sk9hnxgy3zp5usfh3tau", "eab3a1d125a3bf4cd941a6a0b5d7752af96fae7f5bcc641e8a0b6762")
    .outputs_inline_datum_exist(WData::JSON(output_datum.to_string()).to_cbor().unwrap().as_str())
```

### Testing mints

Testing mints with below APIs:

* `token_minted` - checks if a specific token is minted in the transaction
* `only_token_minted` - checks if a specific token is minted in the transaction and that it is the only mint
* `policy_only_minted_token` - checks if a specific token is minted in the transaction, ensuring that it is the only mint for the given policy ID
* `check_policy_only_burn` - checks if a specific policy ID is burned in the transaction, ensuring that it is the only minting (i.e. burning item).

### Testing time

Testing time with below APIs:

* `valid_after` - checks if the transaction is valid after a specified timestamp
* `valid_before` - checks if the transaction is valid before a specified timestamp

### Testing signature

Testing whether the signature is required in the transaction with below APIs:

* `key_signed` - checks if a specific key is signed in the transaction
* `one_of_keys_signed` - checks if any one of the specified keys is signed in the transaction
* `all_keys_signed` - checks if all specified keys are signed in the transaction
