From c828b45f2ac041f6cb4493396cbf51975ff53e32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20Breu=C3=9F?= Date: Sat, 31 Jan 2026 13:59:14 +0100 Subject: [PATCH 1/4] docs: improve property and indexer setup documentation --- Docs/pages/setup/01-properties.md | 54 +++++++++++- Docs/pages/setup/03-indexers.md | 82 +++++++++++++++--- README.md | 136 +++++++++++++++++++++++++++--- 3 files changed, 245 insertions(+), 27 deletions(-) diff --git a/Docs/pages/setup/01-properties.md b/Docs/pages/setup/01-properties.md index 55b5017b..2b3254aa 100644 --- a/Docs/pages/setup/01-properties.md +++ b/Docs/pages/setup/01-properties.md @@ -13,7 +13,7 @@ sut.SetupMock.Property.TotalDispensed.InitializeWith(42); ## Returns / Throws -Alternatively, set up properties with `Returns` and `Throws` (supports sequences): +Set up properties with `Returns` and `Throws` (supports sequences): ```csharp sut.SetupMock.Property.TotalDispensed @@ -23,11 +23,59 @@ sut.SetupMock.Property.TotalDispensed .Returns(4); ``` +You can also return a value based on the previous value: + +```csharp +sut.SetupMock.Property.TotalDispensed + .Returns(current => current + 10); // Increment by 10 each read +``` + ## Callbacks Register callbacks on the setter or getter: ```csharp -sut.SetupMock.Property.TotalDispensed.OnGet.Do(() => Console.WriteLine("TotalDispensed was read!")); -sut.SetupMock.Property.TotalDispensed.OnSet.Do((oldValue, newValue) => Console.WriteLine($"Changed from {oldValue} to {newValue}!") ); +sut.SetupMock.Property.TotalDispensed.OnGet + .Do(() => Console.WriteLine("TotalDispensed was read!")); +sut.SetupMock.Property.TotalDispensed.OnSet + .Do(newValue => Console.WriteLine($"Changed to {newValue}!") ); +``` + +Callbacks can also receive the invocation counter and current value: + +```csharp +// Getter with counter and current value +sut.SetupMock.Property.TotalDispensed + .OnGet.Do((int count, int value) => + Console.WriteLine($"[#{count}] Read TotalDispensed current value: {value}")); + +// Setter with counter and new value +sut.SetupMock.Property.TotalDispensed + .OnSet.Do((int count, int newValue) => + Console.WriteLine($"[#{count}] Set TotalDispensed to {newValue}")); +``` + +Callbacks also support sequences, similar to `Returns` and `Throws`: + +```csharp +sut.SetupMock.Property.TotalDispensed.OnGet + .Do(() => Console.WriteLine("Execute on all even read interactions")) + .Do(() => Console.WriteLine("Execute on all odd read interactions")); +``` + +**Note:** +All callbacks support more advanced features like conditional execution, frequency control, parallel execution, and +access to the invocation counter. +See [Advanced callback features](https://awexpect.com/docs/mockolate/advanced-features/advanced-callback-features) for +details. + +## Register + +Register a setup without providing a value (useful when `ThrowWhenNotSetup` is enabled): + +```csharp +var strictMock = Mock.Create(MockBehavior.Default.ThrowingWhenNotSetup()); + +// Register property without value - won't throw +strictMock.SetupMock.Property.TotalDispensed.Register(); ``` diff --git a/Docs/pages/setup/03-indexers.md b/Docs/pages/setup/03-indexers.md index 8fe95e5a..06d6f830 100644 --- a/Docs/pages/setup/03-indexers.md +++ b/Docs/pages/setup/03-indexers.md @@ -12,16 +12,76 @@ sut.SetupMock.Indexer(It.Is("Dark")) .OnSet.Do((value, type) => Console.WriteLine($"Set [{type}] to {value}")); ``` -- `.InitializeWith(…)` can take a value or a callback with parameters. -- `.Returns(…)` and `.Throws(…)` support direct values, callbacks, and callbacks with parameters and/or the current - value. -- `.OnGet.Do(…)` and `.OnSet.Do(…)` support callbacks with or without parameters. -- `.Returns(…)` and `.Throws(…)` can be chained to define a sequence of behaviors, which are cycled through on each - call. +## Initialization + +You can initialize indexers so they work like normal indexers (setter changes the value, getter returns the last set +value): + +```csharp +sut.SetupMock.Indexer(It.IsAny()).InitializeWith(42); +``` + +## Returns / Throws + +Set up indexers with `Returns` and `Throws` (supports sequences): + +```csharp +sut.SetupMock.Indexer(It.IsAny()) + .Returns(1) + .Returns(2) + .Throws(new Exception("Error")) + .Returns(4); +``` + +You can also return a value based on the previous value: + +```csharp +sut.SetupMock.Indexer(It.IsAny()) + .Returns(current => current + 10); // Increment by 10 each read +``` + +## Callbacks + +Register callbacks on the setter or getter of the indexer: + +```csharp +sut.SetupMock.Indexer(It.IsAny()).OnGet + .Do(() => Console.WriteLine("Indexer was read!")); +sut.SetupMock.Indexer(It.IsAny()).OnSet + .Do(newValue => Console.WriteLine($"Changed indexer to {newValue}!") ); +sut.SetupMock.Indexer(It.IsAny()).OnSet + .Do((index, newValue) => Console.WriteLine($"Changed this[{index}] to {newValue}!") ); +``` + +Callbacks can also receive the invocation counter and current value: + +```csharp +// Getter with counter and current value +sut.SetupMock.Indexer(It.IsAny()) + .OnGet.Do((int count, string index, int value) => + Console.WriteLine($"[#{count}] Read this[{index}] current value: {value}")); + +// Setter with counter and new value +sut.SetupMock.Indexer(It.IsAny()) + .OnSet.Do((int count, string index, int newValue) => + Console.WriteLine($"[#{count}] Set this[{index}] to {newValue}")); +``` + +Callbacks also support sequences, similar to `Returns` and `Throws`: + +```csharp +sut.SetupMock.Indexer(It.IsAny()).OnGet + .Do(() => Console.WriteLine("Execute on all even read interactions")) + .Do(() => Console.WriteLine("Execute on all odd read interactions")); +``` + +**Notes:** +- All callbacks support more advanced features like conditional execution, frequency control, parallel execution, and + access to the invocation counter. + See [Advanced callback features](https://awexpect.com/docs/mockolate/advanced-features/advanced-callback-features) for + details. +- You can use the same [parameter matching](https://awexpect.com/docs/mockolate/setup/parameter-matching) + and [interaction](https://awexpect.com/docs/mockolate/setup/parameter-matching#parameter-interaction) options as for + methods. - Use `.SkippingBaseClass(…)` to override the base class behavior for a specific indexer (only for class mocks). - When you specify overlapping setups, the most recently defined setup takes precedence. - -**Note**: -You can use the same [parameter matching](https://awexpect.com/docs/mockolate/setup/parameter-matching) -and [interaction](https://awexpect.com/docs/mockolate/setup/parameter-matching#parameter-interaction) options as for -methods. diff --git a/README.md b/README.md index 7053a80b..65fb429c 100644 --- a/README.md +++ b/README.md @@ -208,7 +208,7 @@ sut.SetupMock.Property.TotalDispensed.InitializeWith(42); **Returns / Throws** -Alternatively, set up properties with `Returns` and `Throws` (supports sequences): +Set up properties with `Returns` and `Throws` (supports sequences): ```csharp sut.SetupMock.Property.TotalDispensed @@ -218,13 +218,61 @@ sut.SetupMock.Property.TotalDispensed .Returns(4); ``` +You can also return a value based on the previous value: + +```csharp +sut.SetupMock.Property.TotalDispensed + .Returns(current => current + 10); // Increment by 10 each read +``` + **Callbacks** Register callbacks on the setter or getter: ```csharp -sut.SetupMock.Property.TotalDispensed.OnGet.Do(() => Console.WriteLine("TotalDispensed was read!")); -sut.SetupMock.Property.TotalDispensed.OnSet.Do((oldValue, newValue) => Console.WriteLine($"Changed from {oldValue} to {newValue}!") ); +sut.SetupMock.Property.TotalDispensed.OnGet + .Do(() => Console.WriteLine("TotalDispensed was read!")); +sut.SetupMock.Property.TotalDispensed.OnSet + .Do(newValue => Console.WriteLine($"Changed to {newValue}!") ); +``` + +Callbacks can also receive the invocation counter and current value: + +```csharp +// Getter with counter and current value +sut.SetupMock.Property.TotalDispensed + .OnGet.Do((int count, int value) => + Console.WriteLine($"[#{count}] Read TotalDispensed current value: {value}")); + +// Setter with counter and new value +sut.SetupMock.Property.TotalDispensed + .OnSet.Do((int count, int newValue) => + Console.WriteLine($"[#{count}] Set TotalDispensed to {newValue}")); +``` + +Callbacks also support sequences, similar to `Returns` and `Throws`: + +```csharp +sut.SetupMock.Property.TotalDispensed.OnGet + .Do(() => Console.WriteLine("Execute on all even read interactions")) + .Do(() => Console.WriteLine("Execute on all odd read interactions")); +``` + +*Note:* +All callbacks support more advanced features like conditional execution, frequency control, parallel execution, and +access to the invocation counter. +See [Advanced callback features](#advanced-callback-features) for +details. + +**Register** + +Register a setup without providing a value (useful when `ThrowWhenNotSetup` is enabled): + +```csharp +var strictMock = Mock.Create(MockBehavior.Default.ThrowingWhenNotSetup()); + +// Register property without value - won't throw +strictMock.SetupMock.Property.TotalDispensed.Register(); ``` ### Methods @@ -290,19 +338,81 @@ sut.SetupMock.Indexer(It.Is("Dark")) .OnSet.Do((value, type) => Console.WriteLine($"Set [{type}] to {value}")); ``` -- `.InitializeWith(…)` can take a value or a callback with parameters. -- `.Returns(…)` and `.Throws(…)` support direct values, callbacks, and callbacks with parameters and/or the current - value. -- `.OnGet.Do(…)` and `.OnSet.Do(…)` support callbacks with or without parameters. -- `.Returns(…)` and `.Throws(…)` can be chained to define a sequence of behaviors, which are cycled through on each - call. +**Initialization** + +You can initialize indexers so they work like normal indexers (setter changes the value, getter returns the last set +value): + +```csharp +sut.SetupMock.Indexer(It.IsAny()).InitializeWith(42); +``` + +**Returns / Throws** + +Set up indexers with `Returns` and `Throws` (supports sequences): + +```csharp +sut.SetupMock.Indexer(It.IsAny()) + .Returns(1) + .Returns(2) + .Throws(new Exception("Error")) + .Returns(4); +``` + +You can also return a value based on the previous value: + +```csharp +sut.SetupMock.Indexer(It.IsAny()) + .Returns(current => current + 10); // Increment by 10 each read +``` + +**Callbacks** + +Register callbacks on the setter or getter of the indexer: + +```csharp +sut.SetupMock.Indexer(It.IsAny()).OnGet + .Do(() => Console.WriteLine("Indexer was read!")); +sut.SetupMock.Indexer(It.IsAny()).OnSet + .Do(newValue => Console.WriteLine($"Changed indexer to {newValue}!") ); +sut.SetupMock.Indexer(It.IsAny()).OnSet + .Do((index, newValue) => Console.WriteLine($"Changed this[{index}] to {newValue}!") ); +``` + +Callbacks can also receive the invocation counter and current value: + +```csharp +// Getter with counter and current value +sut.SetupMock.Indexer(It.IsAny()) + .OnGet.Do((int count, string index, int value) => + Console.WriteLine($"[#{count}] Read this[{index}] current value: {value}")); + +// Setter with counter and new value +sut.SetupMock.Indexer(It.IsAny()) + .OnSet.Do((int count, string index, int newValue) => + Console.WriteLine($"[#{count}] Set this[{index}] to {newValue}")); +``` + +Callbacks also support sequences, similar to `Returns` and `Throws`: + +```csharp +sut.SetupMock.Indexer(It.IsAny()).OnGet + .Do(() => Console.WriteLine("Execute on all even read interactions")) + .Do(() => Console.WriteLine("Execute on all odd read interactions")); +``` + +**Notes:** + +- All callbacks support more advanced features like conditional execution, frequency control, parallel execution, and + access to the invocation counter. + See [Advanced callback features](#advanced-callback-features) for + details. +- You can use the same [parameter matching](#parameter-matching) + and [interaction](#parameter-interaction) options as for + methods. - Use `.SkippingBaseClass(…)` to override the base class behavior for a specific indexer (only for class mocks). - When you specify overlapping setups, the most recently defined setup takes precedence. -**Note**: -You can use the same [parameter matching](#parameter-matching) and [interaction](#parameter-interaction) options as for -methods. - ### Parameter Matching Mockolate provides flexible parameter matching for method setups and verifications: From 9ef7911a47b6a9cf3fc23d6e45bf61d18647aa74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20Breu=C3=9F?= Date: Sat, 31 Jan 2026 14:11:47 +0100 Subject: [PATCH 2/4] Fix review issues --- Docs/pages/setup/01-properties.md | 10 +++++----- README.md | 9 ++++----- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/Docs/pages/setup/01-properties.md b/Docs/pages/setup/01-properties.md index 2b3254aa..e50258dc 100644 --- a/Docs/pages/setup/01-properties.md +++ b/Docs/pages/setup/01-properties.md @@ -63,11 +63,11 @@ sut.SetupMock.Property.TotalDispensed.OnGet .Do(() => Console.WriteLine("Execute on all odd read interactions")); ``` -**Note:** -All callbacks support more advanced features like conditional execution, frequency control, parallel execution, and -access to the invocation counter. -See [Advanced callback features](https://awexpect.com/docs/mockolate/advanced-features/advanced-callback-features) for -details. +**Notes:** +- All callbacks support more advanced features like conditional execution, frequency control, parallel execution, and + access to the invocation counter. + See [Advanced callback features](https://awexpect.com/docs/mockolate/advanced-features/advanced-callback-features) + for details. ## Register diff --git a/README.md b/README.md index 65fb429c..5ee1f066 100644 --- a/README.md +++ b/README.md @@ -258,11 +258,10 @@ sut.SetupMock.Property.TotalDispensed.OnGet .Do(() => Console.WriteLine("Execute on all odd read interactions")); ``` -*Note:* -All callbacks support more advanced features like conditional execution, frequency control, parallel execution, and -access to the invocation counter. -See [Advanced callback features](#advanced-callback-features) for -details. +*Notes:* +- All callbacks support more advanced features like conditional execution, frequency control, parallel execution, and + access to the invocation counter. + See [Advanced callback features](#advanced-callback-features) for details. **Register** From 1fa9b1b3eed7b6ec249dd135e3c0986ae46fbd48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20Breu=C3=9F?= Date: Sat, 31 Jan 2026 14:13:20 +0100 Subject: [PATCH 3/4] Move register --- Docs/pages/setup/01-properties.md | 21 ++++++++++----------- README.md | 21 ++++++++++----------- 2 files changed, 20 insertions(+), 22 deletions(-) diff --git a/Docs/pages/setup/01-properties.md b/Docs/pages/setup/01-properties.md index e50258dc..52194f65 100644 --- a/Docs/pages/setup/01-properties.md +++ b/Docs/pages/setup/01-properties.md @@ -11,6 +11,15 @@ value): sut.SetupMock.Property.TotalDispensed.InitializeWith(42); ``` +You can also register a setup without providing a value (useful when `ThrowWhenNotSetup` is enabled): + +```csharp +var strictMock = Mock.Create(MockBehavior.Default.ThrowingWhenNotSetup()); + +// Register property without value - won't throw +strictMock.SetupMock.Property.TotalDispensed.Register(); +``` + ## Returns / Throws Set up properties with `Returns` and `Throws` (supports sequences): @@ -64,18 +73,8 @@ sut.SetupMock.Property.TotalDispensed.OnGet ``` **Notes:** + - All callbacks support more advanced features like conditional execution, frequency control, parallel execution, and access to the invocation counter. See [Advanced callback features](https://awexpect.com/docs/mockolate/advanced-features/advanced-callback-features) for details. - -## Register - -Register a setup without providing a value (useful when `ThrowWhenNotSetup` is enabled): - -```csharp -var strictMock = Mock.Create(MockBehavior.Default.ThrowingWhenNotSetup()); - -// Register property without value - won't throw -strictMock.SetupMock.Property.TotalDispensed.Register(); -``` diff --git a/README.md b/README.md index 5ee1f066..7c0b7be1 100644 --- a/README.md +++ b/README.md @@ -206,6 +206,15 @@ value): sut.SetupMock.Property.TotalDispensed.InitializeWith(42); ``` +You can also register a setup without providing a value (useful when `ThrowWhenNotSetup` is enabled): + +```csharp +var strictMock = Mock.Create(MockBehavior.Default.ThrowingWhenNotSetup()); + +// Register property without value - won't throw +strictMock.SetupMock.Property.TotalDispensed.Register(); +``` + **Returns / Throws** Set up properties with `Returns` and `Throws` (supports sequences): @@ -259,21 +268,11 @@ sut.SetupMock.Property.TotalDispensed.OnGet ``` *Notes:* + - All callbacks support more advanced features like conditional execution, frequency control, parallel execution, and access to the invocation counter. See [Advanced callback features](#advanced-callback-features) for details. -**Register** - -Register a setup without providing a value (useful when `ThrowWhenNotSetup` is enabled): - -```csharp -var strictMock = Mock.Create(MockBehavior.Default.ThrowingWhenNotSetup()); - -// Register property without value - won't throw -strictMock.SetupMock.Property.TotalDispensed.Register(); -``` - ### Methods Use `mock.SetupMock.Method.MethodName(…)` to set up methods. You can specify argument matchers for each parameter. From f49b26401e2b8eaf88447eafc80752b480dd0e97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20Breu=C3=9F?= Date: Sat, 31 Jan 2026 14:21:02 +0100 Subject: [PATCH 4/4] Fix review issues --- Docs/pages/setup/01-properties.md | 18 +++++++-------- Docs/pages/setup/03-indexers.md | 20 ++++++++-------- README.md | 38 +++++++++++++++---------------- 3 files changed, 36 insertions(+), 40 deletions(-) diff --git a/Docs/pages/setup/01-properties.md b/Docs/pages/setup/01-properties.md index 52194f65..ef8023d5 100644 --- a/Docs/pages/setup/01-properties.md +++ b/Docs/pages/setup/01-properties.md @@ -50,26 +50,26 @@ sut.SetupMock.Property.TotalDispensed.OnSet .Do(newValue => Console.WriteLine($"Changed to {newValue}!") ); ``` -Callbacks can also receive the invocation counter and current value: +Callbacks can also receive the current value: ```csharp -// Getter with counter and current value +// Getter with the current value sut.SetupMock.Property.TotalDispensed - .OnGet.Do((int count, int value) => - Console.WriteLine($"[#{count}] Read TotalDispensed current value: {value}")); + .OnGet.Do(value => + Console.WriteLine($"Read TotalDispensed current value: {value}")); -// Setter with counter and new value +// Setter with the new value sut.SetupMock.Property.TotalDispensed - .OnSet.Do((int count, int newValue) => - Console.WriteLine($"[#{count}] Set TotalDispensed to {newValue}")); + .OnSet.Do(newValue => + Console.WriteLine($"Set TotalDispensed to {newValue}")); ``` Callbacks also support sequences, similar to `Returns` and `Throws`: ```csharp sut.SetupMock.Property.TotalDispensed.OnGet - .Do(() => Console.WriteLine("Execute on all even read interactions")) - .Do(() => Console.WriteLine("Execute on all odd read interactions")); + .Do(() => Console.WriteLine("Execute on all even read interactions")) + .Do(() => Console.WriteLine("Execute on all odd read interactions")); ``` **Notes:** diff --git a/Docs/pages/setup/03-indexers.md b/Docs/pages/setup/03-indexers.md index 06d6f830..fbf9d7ec 100644 --- a/Docs/pages/setup/03-indexers.md +++ b/Docs/pages/setup/03-indexers.md @@ -49,30 +49,28 @@ sut.SetupMock.Indexer(It.IsAny()).OnGet .Do(() => Console.WriteLine("Indexer was read!")); sut.SetupMock.Indexer(It.IsAny()).OnSet .Do(newValue => Console.WriteLine($"Changed indexer to {newValue}!") ); -sut.SetupMock.Indexer(It.IsAny()).OnSet - .Do((index, newValue) => Console.WriteLine($"Changed this[{index}] to {newValue}!") ); ``` -Callbacks can also receive the invocation counter and current value: +Callbacks can also receive the indexer parameters and the current value: ```csharp -// Getter with counter and current value +// Getter with the current value sut.SetupMock.Indexer(It.IsAny()) - .OnGet.Do((int count, string index, int value) => - Console.WriteLine($"[#{count}] Read this[{index}] current value: {value}")); + .OnGet.Do((string index, int value) => + Console.WriteLine($"Read this[{index}] current value: {value}")); -// Setter with counter and new value +// Setter with the new value sut.SetupMock.Indexer(It.IsAny()) - .OnSet.Do((int count, string index, int newValue) => - Console.WriteLine($"[#{count}] Set this[{index}] to {newValue}")); + .OnSet.Do((string index, int newValue) => + Console.WriteLine($"Set this[{index}] to {newValue}")); ``` Callbacks also support sequences, similar to `Returns` and `Throws`: ```csharp sut.SetupMock.Indexer(It.IsAny()).OnGet - .Do(() => Console.WriteLine("Execute on all even read interactions")) - .Do(() => Console.WriteLine("Execute on all odd read interactions")); + .Do(() => Console.WriteLine("Execute on all even read interactions")) + .Do(() => Console.WriteLine("Execute on all odd read interactions")); ``` **Notes:** diff --git a/README.md b/README.md index 7c0b7be1..87a03347 100644 --- a/README.md +++ b/README.md @@ -245,26 +245,26 @@ sut.SetupMock.Property.TotalDispensed.OnSet .Do(newValue => Console.WriteLine($"Changed to {newValue}!") ); ``` -Callbacks can also receive the invocation counter and current value: +Callbacks can also receive the current value: ```csharp -// Getter with counter and current value +// Getter with the current value sut.SetupMock.Property.TotalDispensed - .OnGet.Do((int count, int value) => - Console.WriteLine($"[#{count}] Read TotalDispensed current value: {value}")); + .OnGet.Do(value => + Console.WriteLine($"Read TotalDispensed current value: {value}")); -// Setter with counter and new value +// Setter with the new value sut.SetupMock.Property.TotalDispensed - .OnSet.Do((int count, int newValue) => - Console.WriteLine($"[#{count}] Set TotalDispensed to {newValue}")); + .OnSet.Do(newValue => + Console.WriteLine($"Set TotalDispensed to {newValue}")); ``` Callbacks also support sequences, similar to `Returns` and `Throws`: ```csharp sut.SetupMock.Property.TotalDispensed.OnGet - .Do(() => Console.WriteLine("Execute on all even read interactions")) - .Do(() => Console.WriteLine("Execute on all odd read interactions")); + .Do(() => Console.WriteLine("Execute on all even read interactions")) + .Do(() => Console.WriteLine("Execute on all odd read interactions")); ``` *Notes:* @@ -373,30 +373,28 @@ sut.SetupMock.Indexer(It.IsAny()).OnGet .Do(() => Console.WriteLine("Indexer was read!")); sut.SetupMock.Indexer(It.IsAny()).OnSet .Do(newValue => Console.WriteLine($"Changed indexer to {newValue}!") ); -sut.SetupMock.Indexer(It.IsAny()).OnSet - .Do((index, newValue) => Console.WriteLine($"Changed this[{index}] to {newValue}!") ); ``` -Callbacks can also receive the invocation counter and current value: +Callbacks can also receive the indexer parameters and the current value: ```csharp -// Getter with counter and current value +// Getter with the current value sut.SetupMock.Indexer(It.IsAny()) - .OnGet.Do((int count, string index, int value) => - Console.WriteLine($"[#{count}] Read this[{index}] current value: {value}")); + .OnGet.Do((string index, int value) => + Console.WriteLine($"Read this[{index}] current value: {value}")); -// Setter with counter and new value +// Setter with the new value sut.SetupMock.Indexer(It.IsAny()) - .OnSet.Do((int count, string index, int newValue) => - Console.WriteLine($"[#{count}] Set this[{index}] to {newValue}")); + .OnSet.Do((string index, int newValue) => + Console.WriteLine($"Set this[{index}] to {newValue}")); ``` Callbacks also support sequences, similar to `Returns` and `Throws`: ```csharp sut.SetupMock.Indexer(It.IsAny()).OnGet - .Do(() => Console.WriteLine("Execute on all even read interactions")) - .Do(() => Console.WriteLine("Execute on all odd read interactions")); + .Do(() => Console.WriteLine("Execute on all even read interactions")) + .Do(() => Console.WriteLine("Execute on all odd read interactions")); ``` **Notes:**