Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 50 additions & 3 deletions Docs/pages/setup/01-properties.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,18 @@ 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<IChocolateDispenser>(MockBehavior.Default.ThrowingWhenNotSetup());

// Register property without value - won't throw
strictMock.SetupMock.Property.TotalDispensed.Register();
```

## 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
Expand All @@ -23,11 +32,49 @@ 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 current value:

```csharp
// Getter with the current value
sut.SetupMock.Property.TotalDispensed
.OnGet.Do(value =>
Console.WriteLine($"Read TotalDispensed current value: {value}"));

// Setter with the new value
sut.SetupMock.Property.TotalDispensed
.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"));
```

**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.
80 changes: 69 additions & 11 deletions Docs/pages/setup/03-indexers.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,74 @@ 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<string>()).InitializeWith(42);
```

## Returns / Throws

Set up indexers with `Returns` and `Throws` (supports sequences):

```csharp
sut.SetupMock.Indexer(It.IsAny<string>())
.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<string>())
.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<string>()).OnGet
.Do(() => Console.WriteLine("Indexer was read!"));
sut.SetupMock.Indexer(It.IsAny<string>()).OnSet
.Do(newValue => Console.WriteLine($"Changed indexer to {newValue}!") );
```

Callbacks can also receive the indexer parameters and the current value:

```csharp
// Getter with the current value
sut.SetupMock.Indexer(It.IsAny<string>())
.OnGet.Do((string index, int value) =>
Console.WriteLine($"Read this[{index}] current value: {value}"));

// Setter with the new value
sut.SetupMock.Indexer(It.IsAny<string>())
.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<string>()).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.
132 changes: 119 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -206,9 +206,18 @@ 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<IChocolateDispenser>(MockBehavior.Default.ThrowingWhenNotSetup());

// Register property without value - won't throw
strictMock.SetupMock.Property.TotalDispensed.Register();
```

**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
Expand All @@ -218,15 +227,52 @@ 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 current value:

```csharp
// Getter with the current value
sut.SetupMock.Property.TotalDispensed
.OnGet.Do(value =>
Console.WriteLine($"Read TotalDispensed current value: {value}"));

// Setter with the new value
sut.SetupMock.Property.TotalDispensed
.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"));
```

*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.

### Methods

Use `mock.SetupMock.Method.MethodName(…)` to set up methods. You can specify argument matchers for each parameter.
Expand Down Expand Up @@ -290,19 +336,79 @@ 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<string>()).InitializeWith(42);
```

**Returns / Throws**

Set up indexers with `Returns` and `Throws` (supports sequences):

```csharp
sut.SetupMock.Indexer(It.IsAny<string>())
.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<string>())
.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<string>()).OnGet
.Do(() => Console.WriteLine("Indexer was read!"));
sut.SetupMock.Indexer(It.IsAny<string>()).OnSet
.Do(newValue => Console.WriteLine($"Changed indexer to {newValue}!") );
```

Callbacks can also receive the indexer parameters and the current value:

```csharp
// Getter with the current value
sut.SetupMock.Indexer(It.IsAny<string>())
.OnGet.Do((string index, int value) =>
Console.WriteLine($"Read this[{index}] current value: {value}"));

// Setter with the new value
sut.SetupMock.Indexer(It.IsAny<string>())
.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<string>()).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:
Expand Down
Loading