Skip to content

Method Callbacks

Callbacks run after the arranged result (or after the default result in Implicit mode when no Returns is provided).

Target type used in examples:

Example

using Imposter.Abstractions;

[assembly: GenerateImposter(typeof(Imposter.Tests.Docs.Methods.ICallbackService))]

public interface ICallbackService
{
    int GetNumber();
    int Increment(int v);
    int GenericAllRefKind(out int o, ref string r, in double d, bool[] args);
}

Ordering relative to results

Example

var stages = new List<string>();

imposter.GetNumber()
    .Returns(() => { stages.Add("return"); return 42; })
    .Callback(() => stages.Add("first"))
    .Callback(() => stages.Add("second"));

service.GetNumber();
// stages == ["return", "first", "second"]

Parameterized callbacks

Capture input arguments in a callback:

Example

imposter.Increment(Arg<int>.Any()).Callback(v => Logger.Log($"value: {v}"));

Ref/out/in with callbacks

Callbacks can work with out, ref, and in parameters. Use OutArg<T>.Any() to match out parameters in the setup signature.

Example

imposter.GenericAllRefKind<int, string, double, bool, int>(
        OutArg<int>.Any(),
        Arg<string>.Any(),
        Arg<double>.Any(),
        Arg<bool[]>.Any())
    .Returns((out int o, ref string r, in double d, bool[] args) => { o = 5; return 99; })
    .Callback((out int o, ref string r, in double d, bool[] args) => { o = 5; /* side-effects */ });

Sequence-local callbacks

Callbacks are scoped to the sequence step they’re defined on. Use Then() to create a new step with independent callbacks.

Example

var seen = new List<string>();

imposter.Increment(Arg<int>.Any())
    .Returns(_ => 10)
    .Callback(_ => seen.Add("first"))
    .Then()
    .Returns(_ => 20)
    .Callback(_ => seen.Add("second"));

service.Increment(1); // adds "first"
service.Increment(2); // adds "second"

Callbacks that throw

If a callback throws, the exception is propagated to the caller after the result has been produced.

Example

// See more examples in repo tests
imposter.GetNumber()
    .Returns(1)
    .Callback(() => throw new InvalidOperationException("boom"));

// service.GetNumber() returns 1, then throws InvalidOperationException