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
2 changes: 1 addition & 1 deletion Docs/pages/01-create-mocks.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ var sut2 = factory.Create<ILemonadeDispenser>();
Using a factory allows you to create multiple mocks with identical, centrally configured behavior. This is especially
useful when you need consistent mock setups across multiple tests or for different types.

## Wrapping Existing Instances
## Wrapping existing instances

You can wrap an existing instance with mock tracking using `Mock.Wrap<T>()`. This allows you to track interactions with
a real object:
Expand Down
File renamed without changes.
File renamed without changes.
7 changes: 7 additions & 0 deletions Docs/pages/advanced-features/_category_.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"label": "Advanced Features",
"position": 5,
"link": {
"type": "generated-index"
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Mocking HttpClient
# HttpClient

Mockolate supports mocking `HttpClient` out of the box, with no special configuration required. You can set up, use, and
verify HTTP interactions just like with any other interface or class.
Expand Down
92 changes: 92 additions & 0 deletions Docs/pages/special-types/02-delegates.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# Delegates

Mockolate supports mocking delegates including `Action`, `Func<T>`, and custom delegates.

**Setup**

Use `SetupMock.Delegate(...)` to configure delegate behavior.

```csharp
// Mock Action delegate
Action myAction = Mock.Create<Action>();
myAction.SetupMock.Delegate().Do(() => Console.WriteLine("Action invoked!"));

// Mock Func<T> delegate
Func<int> myFunc = Mock.Create<Func<int>>();
myFunc.SetupMock.Delegate().Returns(42);
```

For custom delegates with parameters:

```csharp
// Define a custom delegate (typically declared at type level)
public delegate int Calculate(int x, string operation);

// Create and setup the mock
Calculate calculator = Mock.Create<Calculate>();
calculator.SetupMock.Delegate(It.IsAny<int>(), It.Is("add"))
.Returns((x, operation) => x + 10);
```

Delegates with `ref` and `out` parameters are also supported:

```csharp
// Define a custom delegate (typically declared at type level)
public delegate void ProcessData(int input, ref int value, out int result);

// Create and setup the mock
ProcessData processor = Mock.Create<ProcessData>();
processor.SetupMock.Delegate(It.IsAny<int>(), It.IsRef<int>(v => v + 1), It.IsOut(() => 100));
```

- Use `.Do(...)` to run code when the delegate is invoked.
- Use `.Returns(...)` to specify the return value for `Func<T>` delegates.
- Use `.Throws(...)` to specify an exception to throw.
- Use `.Returns(...)` and `.Throws(...)` repeatedly to define a sequence of behaviors.
- Full [parameter matching](https://awexpect.com/docs/mockolate/setup#parameter-matching) support for delegate
parameters including `ref` and `out` parameters.

**Verification**

You can verify that delegates were invoked with specific arguments:

```csharp
// Verify Action was invoked at least once
Action myAction = Mock.Create<Action>();
myAction.Invoke();
myAction.VerifyMock.Invoked().AtLeastOnce();

// Verify Func<T> was invoked exactly once
Func<int> myFunc = Mock.Create<Func<int>>();
_ = myFunc();
myFunc.VerifyMock.Invoked().Once();
```

For custom delegates with parameters:

```csharp
// Define a custom delegate (typically declared at type level)
public delegate int Calculate(int x, string operation);

// Create, invoke, and verify the mock
Calculate calculator = Mock.Create<Calculate>();
_ = calculator(5, "add");
calculator.VerifyMock.Invoked(It.IsAny<int>(), It.Is("add")).Once();
```

Delegates with `ref` and `out` parameters are also supported:

```csharp
// Define a custom delegate (typically declared at type level)
public delegate void ProcessData(int input, ref int value, out int result);

// Create, invoke, and verify the mock
ProcessData processor = Mock.Create<ProcessData>();
int val = 0;
processor(1, ref val, out int res);
processor.VerifyMock.Invoked(It.IsAny<int>(), It.IsRef<int>(), It.IsOut<int>()).Once();
```

**Note:**
Delegate parameters also
support [argument matchers](https://awexpect.com/docs/mockolate/verify-interactions#argument-matchers).
Comment thread
vbreuss marked this conversation as resolved.
Comment thread
vbreuss marked this conversation as resolved.
7 changes: 7 additions & 0 deletions Docs/pages/special-types/_category_.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"label": "Special Types",
"position": 6,
"link": {
"type": "generated-index"
}
}
13 changes: 10 additions & 3 deletions Mockolate.slnx
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,16 @@
<File Path="Docs/pages/02-setup.md" />
<File Path="Docs/pages/03-mock-events.md" />
<File Path="Docs/pages/04-verify-interactions.md" />
<File Path="Docs/pages/05-httpclient.md" />
<File Path="Docs/pages/06-analyzers.md" />
<File Path="Docs/pages/07-comparison.md" />
<File Path="Docs/pages/07-analyzers.md" />
<File Path="Docs/pages/08-comparison.md" />
</Folder>
<Folder Name="/_/Docs/advanced-features/">
<File Path="Docs/pages/advanced-features/_category_.json" />
</Folder>
<Folder Name="/_/Docs/special-types/">
<File Path="Docs/pages/special-types/01-httpclient.md" />
<File Path="Docs/pages/special-types/02-delegates.md" />
<File Path="Docs/pages/special-types/_category_.json" />
</Folder>
<Folder Name="/_/Source/">
<File Path="Source/Directory.Build.props" />
Expand Down
98 changes: 96 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ var sut2 = factory.Create<ILemonadeDispenser>();
Using a factory allows you to create multiple mocks with identical, centrally configured behavior. This is especially
useful when you need consistent mock setups across multiple tests or for different types.

## Wrapping Existing Instances
## Wrapping existing instances

You can wrap an existing instance with mock tracking using `Mock.Wrap<T>()`. This allows you to track interactions with
a real object:
Expand Down Expand Up @@ -521,7 +521,9 @@ If the order is incorrect or a call is missing, a `MockVerificationException` wi
This is useful for ensuring that your test setup and test execution match.
If any setup was not used, this method returns `false`.

## Mocking HttpClient
## Special Types

### HttpClient

Mockolate supports mocking `HttpClient` out of the box, with no special configuration required. You can set up, use, and
verify HTTP interactions just like with any other interface or class.
Expand Down Expand Up @@ -553,6 +555,98 @@ httpClient.VerifyMock.Invoked.PostAsync(
As they therefore all forward to the `SendAsync` method, you can mix using a string or an `Uri` parameter in setup or
verification.

### Delegates

Mockolate supports mocking delegates including `Action`, `Func<T>`, and custom delegates.

**Setup**

Use `SetupMock.Delegate(...)` to configure delegate behavior.

```csharp
// Mock Action delegate
Action myAction = Mock.Create<Action>();
myAction.SetupMock.Delegate().Do(() => Console.WriteLine("Action invoked!"));

// Mock Func<T> delegate
Func<int> myFunc = Mock.Create<Func<int>>();
myFunc.SetupMock.Delegate().Returns(42);
```

For custom delegates with parameters:

```csharp
// Define a custom delegate (typically declared at type level)
public delegate int Calculate(int x, string operation);

// Create and setup the mock
Calculate calculator = Mock.Create<Calculate>();
calculator.SetupMock.Delegate(It.IsAny<int>(), It.Is("add"))
.Returns((x, operation) => x + 10);
```

Delegates with `ref` and `out` parameters are also supported:

```csharp
// Define a custom delegate (typically declared at type level)
public delegate void ProcessData(int input, ref int value, out int result);

// Create and setup the mock
ProcessData processor = Mock.Create<ProcessData>();
processor.SetupMock.Delegate(It.IsAny<int>(), It.IsRef<int>(v => v + 1), It.IsOut(() => 100));
```

- Use `.Do(...)` to run code when the delegate is invoked.
- Use `.Returns(...)` to specify the return value for `Func<T>` delegates.
- Use `.Throws(...)` to specify an exception to throw.
- Use `.Returns(...)` and `.Throws(...)` repeatedly to define a sequence of behaviors.
- Full [parameter matching](#parameter-matching) support for delegate
parameters including `ref` and `out` parameters.

**Verification**

You can verify that delegates were invoked with specific arguments:

```csharp
// Verify Action was invoked at least once
Action myAction = Mock.Create<Action>();
myAction.Invoke();
myAction.VerifyMock.Invoked().AtLeastOnce();

// Verify Func<T> was invoked exactly once
Func<int> myFunc = Mock.Create<Func<int>>();
_ = myFunc();
myFunc.VerifyMock.Invoked().Once();
```

For custom delegates with parameters:

```csharp
// Define a custom delegate (typically declared at type level)
public delegate int Calculate(int x, string operation);

// Create, invoke, and verify the mock
Calculate calculator = Mock.Create<Calculate>();
_ = calculator(5, "add");
calculator.VerifyMock.Invoked(It.IsAny<int>(), It.Is("add")).Once();
```

Delegates with `ref` and `out` parameters are also supported:

```csharp
// Define a custom delegate (typically declared at type level)
public delegate void ProcessData(int input, ref int value, out int result);

// Create, invoke, and verify the mock
ProcessData processor = Mock.Create<ProcessData>();
int val = 0;
processor(1, ref val, out int res);
processor.VerifyMock.Invoked(It.IsAny<int>(), It.IsRef<int>(), It.IsOut<int>()).Once();
```

**Note:**
Delegate parameters also support [argument matchers](#argument-matchers).

## Analyzers

Mockolate ships with some Roslyn analyzers to help you adopt best practices and catch issues early, at compile time.
Expand Down
Loading