Mocking creates test doubles for dependencies so tests can isolate behavior or verify communication. It improves tests only when it preserves resistance to refactoring; indiscriminate use creates fragility. section 5.0
Apply mocking through a small set of practical rules:
- Mock unmanaged, usually out-of-process, dependencies; keep managed dependencies concrete unless a genuine abstraction has multiple implementations. section 8.4 section 9.3
- Use mocks in controller integration tests rather than domain-model unit tests, because controllers coordinate communication while domain models handle business complexity. section 9.2
- Verify interactions at the system’s edges, where application behavior meets an external dependency, rather than through an internal wrapper. section 9.1
- Verify expected calls, call counts, and the absence of unexpected calls; the number of mocks depends on the behavior being tested, not a fixed quota. section 9.2 section 9.3
- Mock adapters that you own instead of mocking third-party library types directly. section 9.3
Verify the external message, not the internal wrapper
A CRM email-change integration test initially mocks IMessageBus and verifies SendEmailChangedMessage. Because IMessageBus is an internal wrapper, the test can miss regressions in message translation. Construct MessageBus with a mock IBus instead, then verify the serialized external message once. A handwritten BusSpy offers the same edge-focused check while expressing the expected behavior without mock-framework syntax.
Listing 9.5. Integration test targeting IBus
[Fact]
public void Changing_email_from_corporate_to_non_corporate()
{
var busMock = new Mock<IBus>();
var messageBus = new MessageBus(busMock.Object); #1
var loggerMock = new Mock<IDomainLogger>();
var sut = new UserController(db, messageBus, loggerMock.Object);
/* ... */
busMock.Verify(
x => x.Send(
"Type: USER EMAIL CHANGED; " + #2
$"Id: {user.UserId}; " + #2
"NewEmail: new@gmail.com"), #2
Times.Once);
}
Shows an integration test that mocks the external IBus edge and verifies the emitted message. section 9.1




















