Course contentsShow
← C#
Lesson 1632 of 1,90815. Software Quality and TestingFree lesson

Configuring Mock Behaviors

Set up strict vs loose mock behaviors to control the strictness of interaction verification.

In this lesson, you will learn how to shift the strictness of your mocks to precisely control how your system reacts to unexpected method calls during unit testing.

When we create a mock, we generally choose between two behavioral modes: Loose and Strict. These modes determine how the mock responds when your code invokes a method that wasn't explicitly set up in your test.

Loose Mocks (The Default)

By default, most frameworks like Moq initialize mocks as MockBehavior.Loose. If your code calls a method on a loose mock that you didn't explicitly configure, the mock will return a default value (like null, 0, or an empty collection) and continue execution.

  • Pros: Keeps tests resilient to small changes in dependencies you don't care about.
  • Cons: Can hide bugs where your code interacts with a dependency in an unexpected way.

Strict Mocks

A MockBehavior.Strict mock is the "security guard" of your test. If your code calls any method that you haven't explicitly set up using Setup, the mock immediately throws an exception.

// Creating a strict mock in Moq
var mock = new Mock<IInventoryService>(MockBehavior.Strict);

// If we don't setup 'GetStockCount' and the code calls it:
// The test fails immediately with a MockException.

When to choose which?

Use Loose mocks when you are testing the high-level logic of a class and want to ignore "noise"—side-effect-free calls to secondary dependencies that aren't relevant to the current test case.

Use Strict mocks when you are performing integration-style unit tests or when the interaction order is mission-critical. Strict behavior ensures that your test acts as a contract; if the code calls a method it shouldn't, or calls it with unexpected arguments, the test fails loudly. This approach is highly effective for catching "hidden" calls that you might have forgotten to account for in your design.

Key Takeaway: Use Loose mocks to keep tests maintainable by ignoring irrelevant interactions, and use Strict mocks to enforce a precise, fail-fast contract between your system and its dependencies.