Skip to content

feat: Add spy! macro and #[autospy] attribute#682

Open
exoego wants to merge 2 commits intoasomers:masterfrom
exoego:spy
Open

feat: Add spy! macro and #[autospy] attribute#682
exoego wants to merge 2 commits intoasomers:masterfrom
exoego:spy

Conversation

@exoego
Copy link

@exoego exoego commented Feb 14, 2026

Closes #567

Adds

  • spy! procedural macro (analogous to mock!)
  • #[autospy] attribute macro (analogous to #[automock]) supports both traits and struct impl blocks
  • real.into_spy() helper which is a shorthand for SpyFoo::new(real)

Design decisions:

  1. Spy reuses the existing mock pipeline. Instead of a separate code path, spy generation goes through the same MockItemStruct / MockFunction / MockTrait with a GenerateMode flag. This keeps code duplication low but ties spy behavior to mock internals.
  2. Trait spies are generic: SpyFoo<T: MyTrait> accepts any type that implements the trait. Struct spies use a concrete type directly because inherent methods have no trait to use as a bound.
  3. impl Trait return-types (including plain async fn) are not supported. Because Mockall converts these to Pin<Box<dyn Trait>>, which causes a type mismatch when calling the real implementation.
    • #[async_trait] works because it does this conversion before mockall processes the trait. This is documented as a known limitation.
  4. calling_real() is needed for verified delegation. Unlike Java (Mockito)/Ruby(RSpec) spy frameworks that record all calls and let you check them after the fact, Mockall requires expectations to be set up before the call. So, users must explicitly use calling_real() when they want to both delegate and verify.

@exoego exoego requested a review from asomers as a code owner February 14, 2026 07:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature request: create a spy! macro to provide a transparent mock but that can be asserted upon.

1 participant