Expectation

Struct Expectation 

Source
pub struct Expectation<P: Tokenize + Send + 'static, R: Tokenize + Send + 'static> { /* private fields */ }
Expand description

Expectation for contract method.

A method could have multiple expectations associated with it. Each expectation specifies how the method should be called, how many times, with what arguments, etc.

When a method gets called, mock node determines if the call is expected or not. It goes through each of the method’s expectations in order they were created, searching for the first expectation that matches the call.

If a suitable expectation is found, it is used to determine method’s return value and other transaction properties. If not, the call is considered unexpected, and mock node panics.

To determine if a particular expectation should be used for the given call, mock node uses two of the expectation’s properties:

  • predicate checks if method’s arguments and transaction properties match a certain criteria;
  • times limiter is used to limit number of times a single expectation can be used.

To determine result of a method call, returns property is used.

§Notes

Expectations can’t be changed after they were used. That is, if you try to modify an expectation after making any calls to its contract method, mock node will panic. This happens because modifying an already-used expectation may break node’s internal state. Adding new expectations at any time is fine, though.

Implementations§

Source§

impl<P: Tokenize + Send + 'static, R: Tokenize + Send + 'static> Expectation<P, R>

Source

pub fn times(self, times: impl Into<TimesRange>) -> Self

Specifies how many times this expectation can be called.

By default, each expectation can be called any number of times, including zero. This method allows specifying a more precise range.

For example, use times(1) to indicate that the expectation should be called exactly once. Or use times(1..) to indicate that it should be called at least once. Any range syntax is accepted.

If the expectation gets called less that the specified number of times, the test panics.

If it gets called enough number of times, expectation is considered satisfied. It becomes inactive and is no longer checked when processing new method calls.

§Examples

Consider a method with two expectations:

contract
    .expect_call(signature)
    .times(1..=2);
contract
    .expect_call(signature);

The first two calls to this method will be dispatched to the first expectation. Then first expectation will become satisfied, and all other calls will be dispatched to the second one.

§Notes

When expectation becomes satisfied, previous expectations are not altered and may still be unsatisfied. This is important when you have expectations with predicates:

contract
    .expect_call(signature)
    .predicate_fn(|(a, b)| a == b)
    .times(1..=2);
contract
    .expect_call(signature)
    .times(1);
contract
    .expect_call(signature)
    .times(..);

Here, first expectation can be called one or two times, second expectation can be called exactly once, and third expectation can be called arbitrary number of times.

Now, consider the following sequence of calls:

instance
    .method(signature, (1, 1))?
    .call()
    .await?;
instance
    .method(signature, (2, 3))?
    .call()
    .await?;
instance
    .method(signature, (5, 5))?
    .call()
    .await?;

First call gets dispatched to the first expectation. Second call can’t be dispatched to the first expectation because of its predicate, so it gets dispatched to the second one. Now, one may assume that the third call will be dispatched to the third expectation. However, first expectation can be called one more time, so it is not satisfied yet. Because of this, third call gets dispatched to the first expectation.

Source

pub fn never(self) -> Self

Indicates that this expectation can be called exactly zero times.

See times for more info.

Source

pub fn once(self) -> Self

Indicates that this expectation can be called exactly one time.

See times for more info.

Source

pub fn in_sequence(self, sequence: &mut Sequence) -> Self

Adds this expectation to a sequence.

By default, expectations may be matched in any order. If a stricter order is required, you can use sequences. See mockall documentation for more info.

§Limitations

An expectation can be in one sequence only.

Also, an expectation should have times limit set to an exact number of calls, i.e., once, two times, and so on.

Source

pub fn confirmations(self, confirmations: u64) -> Self

Sets number of blocks that should be mined on top of the transaction block. This method can be useful when there are custom transaction confirmation settings.

Source

pub fn predicate<T>(self, pred: T) -> Self
where T: TuplePredicate<P> + Send + 'static, <T as TuplePredicate<P>>::P: Send,

Sets predicate for this expectation.

If method has multiple expectations, they are checked one-by-one, in order they were created. First expectation with a predicate that matches method’s parameters is called.

This method accepts a tuple of predicates, one predicate for each parameter.

This method will overwrite any predicate that was set before.

§Examples
contract
    .expect_call(signature)
    .predicate((predicate::eq(1), predicate::eq(1)))
    .returns(1);
contract
    .expect_call(signature)
    .predicate_fn(|(a, b)| a > b)
    .returns(2);
contract
    .expect_call(signature)
    .returns(3);

Here, we have three expectations, resulting in the following behaviour. If both arguments are equal to 1, method returns 1. Otherwise, if the first argument is greater than the second one, method returns 2. Otherwise, it returns 3.

§Notes

Having multiple predicates shines for complex setups that involve call sequences and limiting number of expectation uses. For simpler setups like the one above, returns_fn may be more clear and concise, and also more efficient.

Source

pub fn predicate_fn(self, pred: impl Fn(&P) -> bool + Send + 'static) -> Self

Sets predicate function for this expectation. This function accepts a tuple of method’s arguments and returns true if this expectation should be called. See predicate for more info.

This method will overwrite any predicate that was set before.

Source

pub fn predicate_fn_ctx( self, pred: impl Fn(&CallContext, &P) -> bool + Send + 'static, ) -> Self

Sets predicate function for this expectation. This function accepts a call context and a tuple of method’s arguments and returns true if this expectation should be called. See predicate for more info.

This method will overwrite any predicate that was set before.

Source

pub fn allow_calls(self, allow_calls: bool) -> Self

Indicates that this expectation only applies to view calls.

This method will not override predicates set by predicate and similar methods.

See also Contract::expect_call.

Source

pub fn allow_transactions(self, allow_transactions: bool) -> Self

Indicates that this expectation only applies to transactions.

This method will not override predicates set by predicate and similar methods.

See also Contract::expect_transaction.

Source

pub fn returns(self, returns: R) -> Self

Sets return value of the method.

By default, call to this expectation will result in solidity’s default value for the method’s return type. This method allows specifying a custom return value.

This method will overwrite any return value or callback that was set before.

Source

pub fn returns_fn( self, returns: impl Fn(P) -> Result<R, String> + Send + 'static, ) -> Self

Sets callback function that will be used to calculate return value of the method. This function accepts a tuple of method’s arguments and returns method’s result or Err if transaction should be reverted.

A callback set by this method will be called even if its return value is unused, such as when processing a transaction. This means that callback can be used to further check method’s parameters, perform asserts and invoke other logic.

This method will overwrite any return value or callback that was set before.

See returns for more info.

Source

pub fn returns_fn_ctx( self, returns: impl Fn(&CallContext, P) -> Result<R, String> + Send + 'static, ) -> Self

Sets callback function that will be used to calculate return value of the method. This function accepts a call context and a tuple of method’s arguments and returns method’s result or Err if transaction should be reverted.

A callback set by this method will be called even if its return value is unused, such as when processing a transaction. This means that callback can be used to further check method’s parameters, perform asserts and invoke other logic.

This method will overwrite any return value or callback that was set before.

See returns for more info.

Source

pub fn returns_error(self, error: String) -> Self

Sets return value of the method to an error, meaning that calls to this expectation result in reverted transaction.

This method will overwrite any return value or callback that was set before.

See returns for more info.

Source

pub fn returns_default(self) -> Self

Sets return value of the method to a default value for its solidity type. See returns for more info.

This method will overwrite any return value or callback that was set before.

Note that this method doesn’t use Default trait for R. Instead, it constructs default value according to solidity rules.

Auto Trait Implementations§

§

impl<P, R> Freeze for Expectation<P, R>

§

impl<P, R> RefUnwindSafe for Expectation<P, R>

§

impl<P, R> Send for Expectation<P, R>

§

impl<P, R> Sync for Expectation<P, R>
where P: Sync, R: Sync,

§

impl<P, R> Unpin for Expectation<P, R>
where P: Unpin, R: Unpin,

§

impl<P, R> UnwindSafe for Expectation<P, R>
where P: UnwindSafe, R: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Any for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Source§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Source§

fn type_name(&self) -> &'static str

Source§

impl<T> AnySync for T
where T: Any + Send + Sync,

Source§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Send + Sync>

Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V