Skip to content
Closed
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
30 changes: 30 additions & 0 deletions Docs/pages/02-setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -161,3 +161,33 @@ sut.SetupMock.Indexer(It.Is("Dark"))
**Note**:
You can use the same [parameter matching](#parameter-matching) and [interaction](#parameter-interaction) options as for
methods.

## Working with Protected Members

Mockolate allows you to set up and verify protected methods and properties on class mocks. Access protected members using the `.Protected` property:

```csharp
public abstract class ChocolateDispenser
{
protected virtual bool DispenseInternal(string type, int amount) => true;
protected virtual int InternalStock { get; set; }
}

var sut = Mock.Create<ChocolateDispenser>();

// Setup protected method
sut.SetupMock.Protected.Method.DispenseInternal(
It.Is("Dark"), It.IsAny<int>())
.Returns(true);

// Setup protected property
sut.SetupMock.Protected.Property.InternalStock.InitializeWith(100);
```

**Notes:**
- Protected members can be set up and verified just like public members, using the `.Protected` accessor.
- All setup options (`.Returns()`, `.Throws()`, `.Do()`, `.InitializeWith()`, etc.) work with protected members.
- All verification options (`.Once()`, `.AtLeastOnce()`, etc.) work with protected members.
- Protected indexers are supported using `.Protected.Indexer()` for setup and `.GotProtectedIndexer()`/`.SetProtectedIndexer()` for verification.
- For verification examples, see the Protected Members section in the verify interactions documentation.

25 changes: 25 additions & 0 deletions Docs/pages/04-verify-interactions.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,31 @@ sut.VerifyMock.SubscribedTo.ChocolateDispensed().AtLeastOnce();
sut.VerifyMock.UnsubscribedFrom.ChocolateDispensed().Once();
```

## Protected Members

You can verify interactions with protected members on class mocks using the `.Protected` accessor:

```csharp
// Verify protected method was invoked
sut.VerifyMock.Invoked.Protected.DispenseInternal(
It.Is("Dark"), It.IsAny<int>()).Once();

// Verify protected property was read
sut.VerifyMock.Got.Protected.InternalStock().AtLeastOnce();

// Verify protected property was set
sut.VerifyMock.Set.Protected.InternalStock(It.Is(100)).Once();

// Verify protected indexer was read
sut.VerifyMock.GotProtectedIndexer(It.Is(0)).Once();

// Verify protected indexer was set
sut.VerifyMock.SetProtectedIndexer(It.Is(0), It.Is(42)).Once();
```

**Note:**
All verification options (argument matchers, count assertions) work the same for protected members as for public members.

## Call Ordering

Use `Then` to verify that calls occurred in a specific order:
Expand Down
54 changes: 54 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,35 @@ sut.SetupMock.Indexer(It.Is("Dark"))
You can use the same [parameter matching](#parameter-matching) and [interaction](#parameter-interaction) options as for
methods.

### Working with Protected Members

Mockolate allows you to set up and verify protected methods and properties on class mocks. Access protected members using the `.Protected` property:

```csharp
public abstract class ChocolateDispenser
{
protected virtual bool DispenseInternal(string type, int amount) => true;
protected virtual int InternalStock { get; set; }
}

var sut = Mock.Create<ChocolateDispenser>();

// Setup protected method
sut.SetupMock.Protected.Method.DispenseInternal(
It.Is("Dark"), It.IsAny<int>())
.Returns(true);

// Setup protected property
sut.SetupMock.Protected.Property.InternalStock.InitializeWith(100);
```

**Notes:**
- Protected members can be set up and verified just like public members, using the `.Protected` accessor.
- All setup options (`.Returns()`, `.Throws()`, `.Do()`, `.InitializeWith()`, etc.) work with protected members.
- All verification options (`.Once()`, `.AtLeastOnce()`, etc.) work with protected members.
- Protected indexers are supported using `.Protected.Indexer()` for setup and `.GotProtectedIndexer()`/`.SetProtectedIndexer()` for verification.
- See [Protected Members](#protected-members) in the Verify interactions section for verification examples.

## Mock events

Easily raise events on your mock to test event handlers in your code.
Expand Down Expand Up @@ -453,6 +482,31 @@ sut.VerifyMock.SubscribedTo.ChocolateDispensed().AtLeastOnce();
sut.VerifyMock.UnsubscribedFrom.ChocolateDispensed().Once();
```

### Protected Members

You can verify interactions with protected members on class mocks using the `.Protected` accessor:

```csharp
// Verify protected method was invoked
sut.VerifyMock.Invoked.Protected.DispenseInternal(
It.Is("Dark"), It.IsAny<int>()).Once();

// Verify protected property was read
sut.VerifyMock.Got.Protected.InternalStock().AtLeastOnce();

// Verify protected property was set
sut.VerifyMock.Set.Protected.InternalStock(It.Is(100)).Once();

// Verify protected indexer was read
sut.VerifyMock.GotProtectedIndexer(It.Is(0)).Once();

// Verify protected indexer was set
sut.VerifyMock.SetProtectedIndexer(It.Is(0), It.Is(42)).Once();
```

**Note:**
All verification options (argument matchers, count assertions) work the same for protected members as for public members.

### Call Ordering

Use `Then` to verify that calls occurred in a specific order:
Expand Down