Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
34 changes: 34 additions & 0 deletions Docs/pages/advanced-features/03-monitor-interactions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Monitor interactions

Mockolate tracks all interactions with mocks on the mock object. To only track interactions within a given scope, you
can use a `MockMonitor<T>`:

```csharp
var sut = Mock.Create<IChocolateDispenser>();

sut.Dispense("Dark", 1); // Not monitored
using (var monitor = sut.MonitorMock(out var monitor))
Comment thread
vbreuss marked this conversation as resolved.
Outdated
{
sut.Dispense("Dark", 2); // Monitored
}
sut.Dispense("Dark", 3); // Not monitored

// Verifications on the monitor only count interactions during the lifetime scope of the `IDisposable`
monitor.Verify.Invoked.Dispense(It.Is("Dark"), It.IsAny<int>()).Once();
```

## Clear all interactions

For simpler scenarios you can directly clear all recorded interactions on a mock using `ClearAllInteractions` on the
setup:

```csharp
var sut = Mock.Create<IChocolateDispenser>();

sut.Dispense("Dark", 1);
// Clears all previously recorded interactions
sut.SetupMock.ClearAllInteractions();
sut.Dispense("Dark", 2);

monitor.Verify.Invoked.Dispense(It.Is("Dark"), It.IsAny<int>()).Once();
Comment thread
vbreuss marked this conversation as resolved.
Outdated
```
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Check for unexpected interactions

## ThatAllInteractionsAreVerified
## That all interactions are verified

You can check if all interactions with the mock have been verified using `ThatAllInteractionsAreVerified`:

Expand All @@ -12,7 +12,7 @@ bool allVerified = sut.VerifyMock.ThatAllInteractionsAreVerified();
This is useful for ensuring that your test covers all interactions and that no unexpected calls were made.
If any interaction was not verified, this method returns `false`.

## ThatAllSetupsAreUsed
## That all setups are used

You can check if all registered setups on the mock have been used using `ThatAllSetupsAreUsed`:

Expand Down
3 changes: 2 additions & 1 deletion Mockolate.slnx
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@
<Folder Name="/_/Docs/advanced-features/">
<File Path="Docs/pages/advanced-features/01-working-with-protected-members.md" />
<File Path="Docs/pages/advanced-features/02-advanced-callback-features.md" />
<File Path="Docs/pages/advanced-features/03-check-for-unexpected-interactions.md" />
<File Path="Docs/pages/advanced-features/03-monitor-interactions.md" />
<File Path="Docs/pages/advanced-features/04-check-for-unexpected-interactions.md" />
<File Path="Docs/pages/advanced-features/_category_.json" />
</Folder>
<Folder Name="/_/Docs/setup/">
Expand Down
39 changes: 37 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -736,9 +736,44 @@ sut.SetupMock.Property.TotalDispensed.OnGet
.Do((count, value) => Console.WriteLine($"Read #{count}, value: {value}"));
```

### Monitor interactions

Mockolate tracks all interactions with mocks on the mock object. To only track interactions within a given scope, you
can use a `MockMonitor<T>`:

```csharp
var sut = Mock.Create<IChocolateDispenser>();

sut.Dispense("Dark", 1); // Not monitored
using (var monitor = sut.MonitorMock(out var monitor))
Comment thread
vbreuss marked this conversation as resolved.
Outdated
{
sut.Dispense("Dark", 2); // Monitored
}
sut.Dispense("Dark", 3); // Not monitored

// Verifications on the monitor only count interactions during the lifetime scope of the `IDisposable`
monitor.Verify.Invoked.Dispense(It.Is("Dark"), It.IsAny<int>()).Once();
```

#### Clear all interactions

For simpler scenarios you can directly clear all recorded interactions on a mock using `ClearAllInteractions` on the
setup:

```csharp
var sut = Mock.Create<IChocolateDispenser>();

sut.Dispense("Dark", 1);
// Clears all previously recorded interactions
sut.SetupMock.ClearAllInteractions();
sut.Dispense("Dark", 2);

monitor.Verify.Invoked.Dispense(It.Is("Dark"), It.IsAny<int>()).Once();
Comment thread
vbreuss marked this conversation as resolved.
Outdated
```

### Check for unexpected interactions

#### ThatAllInteractionsAreVerified
#### That all interactions are verified

You can check if all interactions with the mock have been verified using `ThatAllInteractionsAreVerified`:

Expand All @@ -750,7 +785,7 @@ bool allVerified = sut.VerifyMock.ThatAllInteractionsAreVerified();
This is useful for ensuring that your test covers all interactions and that no unexpected calls were made.
If any interaction was not verified, this method returns `false`.

#### ThatAllSetupsAreUsed
#### That all setups are used

You can check if all registered setups on the mock have been used using `ThatAllSetupsAreUsed`:

Expand Down
21 changes: 7 additions & 14 deletions Tests/Mockolate.Tests/Monitor/MockMonitorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ public sealed class MockMonitorTests
public async Task ClearAllInteractions_WhenMonitorIsRunning_ShouldClearInternalCollection()
{
IMyService sut = Mock.Create<IMyService>();
Mock<IMyService> mock = ((IMockSubject<IMyService>)sut).Mock;
MockMonitor<IMyService> monitor = new(mock);
sut.MonitorMock(out MockMonitor<IMyService> monitor);

sut.IsValid(1);
using IDisposable disposable = monitor.Run();
Expand All @@ -24,8 +23,7 @@ public async Task ClearAllInteractions_WhenMonitorIsRunning_ShouldClearInternalC
public async Task DisposeTwice_ShouldNotIncludeMoreInvocations()
{
IMyService sut = Mock.Create<IMyService>();
Mock<IMyService> mock = ((IMockSubject<IMyService>)sut).Mock;
MockMonitor<IMyService> monitor = new(mock);
sut.MonitorMock(out MockMonitor<IMyService> monitor);

sut.IsValid(1);
sut.IsValid(2);
Expand Down Expand Up @@ -53,8 +51,7 @@ public async Task DisposeTwice_ShouldNotIncludeMoreInvocations()
public async Task MultipleRun_ShouldMonitorInvocationsDuringTheRun()
{
IMyService sut = Mock.Create<IMyService>();
Mock<IMyService> mock = ((IMockSubject<IMyService>)sut).Mock;
MockMonitor<IMyService> monitor = new(mock);
sut.MonitorMock(out MockMonitor<IMyService> monitor);

sut.IsValid(1);
sut.IsValid(2);
Expand Down Expand Up @@ -91,8 +88,7 @@ public async Task MultipleRun_ShouldMonitorInvocationsDuringTheRun()
public async Task NestedRun_ShouldThrowInvalidOperationException()
{
IMyService sut = Mock.Create<IMyService>();
Mock<IMyService> mock = ((IMockSubject<IMyService>)sut).Mock;
MockMonitor<IMyService> monitor = new(mock);
sut.MonitorMock(out MockMonitor<IMyService> monitor);

void Act()
{
Expand All @@ -113,8 +109,7 @@ await That(Act).Throws<InvalidOperationException>()
public async Task Run_ShouldIncludeAllInvocations()
{
IMyService sut = Mock.Create<IMyService>();
Mock<IMyService> mock = ((IMockSubject<IMyService>)sut).Mock;
MockMonitor<IMyService> monitor = new(mock);
sut.MonitorMock(out MockMonitor<IMyService> monitor);

using (monitor.Run())
{
Expand All @@ -134,8 +129,7 @@ public async Task Run_ShouldIncludeAllInvocations()
public async Task Run_ShouldMonitorInvocationsDuringTheRun()
{
IMyService sut = Mock.Create<IMyService>();
Mock<IMyService> mock = ((IMockSubject<IMyService>)sut).Mock;
MockMonitor<IMyService> monitor = new(mock);
sut.MonitorMock(out MockMonitor<IMyService> monitor);

sut.IsValid(1);
sut.IsValid(2);
Expand Down Expand Up @@ -163,8 +157,7 @@ public async Task Run_ShouldMonitorInvocationsDuringTheRun()
public async Task Verify_WhileRunning_ShouldBeUpToDate()
{
IMyService sut = Mock.Create<IMyService>();
Mock<IMyService> mock = ((IMockSubject<IMyService>)sut).Mock;
MockMonitor<IMyService> monitor = new(mock);
sut.MonitorMock(out MockMonitor<IMyService> monitor);

using (monitor.Run())
{
Expand Down
Loading