# Moq Moq is the most popular and friendly mocking library for .NET, designed to leverage LINQ expression trees and lambda expressions for creating type-safe mock objects. It provides a simple, intuitive API that eliminates the need for record/replay patterns found in other mocking frameworks, making it ideal for both novice and experienced developers practicing test-driven development. The library enables mocking of both interfaces and classes, with full Visual Studio IntelliSense integration. Moq supports strong typing throughout its API, meaning no magic strings for expectations and full compiler verification. Key features include granular control over mock behavior via MockBehavior enumeration, recursive mocking for object hierarchies, event interception and raising, and comprehensive support for out/ref arguments. ## Creating Mocks Create mock objects using the `Mock` constructor, optionally specifying behavior (Loose or Strict). Loose mocks return default values for unexpected calls, while Strict mocks throw exceptions. ```csharp using Moq; public interface IUserService { bool ValidateUser(string username, string password); User GetUser(int id); Task GetUserAsync(int id); } public class User { public int Id { get; set; } public string Name { get; set; } } // Create a loose mock (default behavior) var mockUserService = new Mock(); // Create a strict mock that throws on unexpected calls var strictMock = new Mock(MockBehavior.Strict); // Access the mocked object instance IUserService userService = mockUserService.Object; // Configure CallBase to call base implementation for classes var mockWithCallBase = new Mock { CallBase = true }; // Configure automatic recursive mocking var mockWithAutoMock = new Mock { DefaultValue = DefaultValue.Mock }; ``` ## Setting Up Method Returns with Setup Use `Setup()` combined with `Returns()` to define method behavior. The setup expression uses lambda syntax to specify which method call to intercept. ```csharp using Moq; public interface ICalculator { int Add(int a, int b); string Format(int value); double Divide(int dividend, int divisor); } var mock = new Mock(); // Setup with specific arguments mock.Setup(calc => calc.Add(2, 3)).Returns(5); // Setup with access to invocation arguments mock.Setup(calc => calc.Format(It.IsAny())) .Returns((int value) => $"Result: {value}"); // Setup with lazy evaluation var counter = 0; mock.Setup(calc => calc.Add(It.IsAny(), It.IsAny())) .Returns(() => ++counter); // Usage var calculator = mock.Object; int result = calculator.Add(2, 3); // Returns 5 string formatted = calculator.Format(42); // Returns "Result: 42" int lazy1 = calculator.Add(1, 1); // Returns 1 int lazy2 = calculator.Add(1, 1); // Returns 2 ``` ## Argument Matching with It Class The `It` class provides argument matchers for flexible setup conditions, including `It.IsAny()`, `It.Is()`, `It.IsInRange()`, `It.IsIn()`, `It.IsRegex()`, and `It.Ref.IsAny`. ```csharp using Moq; public interface IEmailService { bool SendEmail(string to, string subject, string body); bool SendToGroup(int[] userIds, string message); } var mock = new Mock(); // Match any string argument mock.Setup(svc => svc.SendEmail( It.IsAny(), It.IsAny(), It.IsAny() )).Returns(true); // Match with predicate condition mock.Setup(svc => svc.SendEmail( It.Is(email => email.Contains("@company.com")), It.IsAny(), It.IsAny() )).Returns(true); // Match with range mock.Setup(svc => svc.SendToGroup( It.Is(ids => ids.Length > 0 && ids.Length <= 100), It.IsAny() )).Returns(true); // Match with regex mock.Setup(svc => svc.SendEmail( It.IsRegex(@"^[\w.-]+@[\w.-]+\.\w+$"), It.IsAny(), It.IsAny() )).Returns(true); // Usage var emailService = mock.Object; bool sent1 = emailService.SendEmail("user@company.com", "Hello", "Body"); // Returns true bool sent2 = emailService.SendEmail("invalid", "Hello", "Body"); // Returns false (no matching setup) ``` ## Setting Up Async Methods Moq provides `ReturnsAsync()` and `ThrowsAsync()` extension methods for async methods, or you can setup the `.Result` property directly (Moq 4.16+). ```csharp using Moq; using System.Threading.Tasks; public interface IDataRepository { Task GetDataAsync(int id); Task SaveDataAsync(string data); Task CountAsync(); } var mock = new Mock(); // Using ReturnsAsync extension method mock.Setup(repo => repo.GetDataAsync(It.IsAny())) .ReturnsAsync("Sample Data"); // Using .Result property (Moq 4.16+) mock.Setup(repo => repo.GetDataAsync(42).Result) .Returns("Specific Data"); // Async method with lazy evaluation mock.Setup(repo => repo.CountAsync()) .ReturnsAsync(() => DateTime.Now.Second); // Setup async void method (Task without result) mock.Setup(repo => repo.SaveDataAsync(It.IsAny())) .Returns(Task.CompletedTask); // Setup async method to throw exception mock.Setup(repo => repo.GetDataAsync(-1)) .ThrowsAsync(new ArgumentException("Invalid ID")); // Usage in async test var repository = mock.Object; string data = await repository.GetDataAsync(42); // Returns "Specific Data" await repository.SaveDataAsync("test"); // Completes successfully await Assert.ThrowsAsync(() => repository.GetDataAsync(-1)); ``` ## Setting Up Properties Use `SetupGet()`, `SetupSet()`, `SetupProperty()`, and `SetupAllProperties()` to configure property behavior including automatic stubbing for getters and setters. ```csharp using Moq; public interface IConfiguration { string ConnectionString { get; set; } int Timeout { get; set; } bool IsEnabled { get; } } var mock = new Mock(); // Setup getter to return a value mock.SetupGet(config => config.ConnectionString) .Returns("Server=localhost;Database=test"); mock.SetupGet(config => config.IsEnabled) .Returns(true); // Setup a trackable property (stub behavior) mock.SetupProperty(config => config.Timeout, 30); // Setup all properties to be trackable mock.SetupAllProperties(); // Verify setter was called with specific value mock.SetupSet(config => config.ConnectionString = "new-value") .Verifiable(); // Usage var config = mock.Object; string connStr = config.ConnectionString; // Returns "Server=localhost;Database=test" config.Timeout = 60; // Sets value int timeout = config.Timeout; // Returns 60 (tracked) config.ConnectionString = "new-value"; // Triggers verifiable setup mock.Verify(); // Passes verification ``` ## Recursive Mocking (Auto-Mocking Hierarchies) Moq supports recursive/hierarchical mocking, allowing you to setup properties and methods on nested objects in a single expression. ```csharp using Moq; public interface IOrder { ICustomer Customer { get; } IAddress ShippingAddress { get; } } public interface ICustomer { string Name { get; } IAddress BillingAddress { get; } } public interface IAddress { string City { get; } string Country { get; } } var mock = new Mock(); // Setup nested properties in a single expression mock.Setup(order => order.Customer.Name).Returns("John Doe"); mock.Setup(order => order.Customer.BillingAddress.City).Returns("New York"); mock.Setup(order => order.ShippingAddress.Country).Returns("USA"); // Enable automatic recursive mocking mock.DefaultValue = DefaultValue.Mock; // Usage var order = mock.Object; string name = order.Customer.Name; // Returns "John Doe" string city = order.Customer.BillingAddress.City; // Returns "New York" string country = order.ShippingAddress.Country; // Returns "USA" // Access auto-created nested mock for further setup var customerMock = Mock.Get(order.Customer); customerMock.Setup(c => c.Name).Returns("Jane Doe"); ``` ## Callbacks Use `Callback()` to execute code when a mocked method is called. Callbacks can access invocation arguments and run before or after the return value is determined. ```csharp using Moq; using System.Collections.Generic; public interface ILogger { void Log(string message); bool LogWithLevel(string level, string message); } var mock = new Mock(); var loggedMessages = new List(); var callCount = 0; // Simple callback mock.Setup(logger => logger.Log(It.IsAny())) .Callback(() => callCount++); // Callback with argument capture mock.Setup(logger => logger.Log(It.IsAny())) .Callback(msg => loggedMessages.Add(msg)); // Callback with multiple parameters mock.Setup(logger => logger.LogWithLevel(It.IsAny(), It.IsAny())) .Callback((level, msg) => loggedMessages.Add($"[{level}] {msg}")) .Returns(true); // Callbacks before and after Returns mock.Setup(logger => logger.LogWithLevel("ERROR", It.IsAny())) .Callback(() => Console.WriteLine("Before logging")) .Returns(true) .Callback(() => Console.WriteLine("After logging")); // Usage var logger = mock.Object; logger.Log("Test message"); logger.LogWithLevel("INFO", "Application started"); logger.LogWithLevel("ERROR", "Something went wrong"); // loggedMessages contains: ["Test message", "[INFO] Application started", "[ERROR] Something went wrong"] ``` ## Sequential Returns with SetupSequence Use `SetupSequence()` to configure different return values or behaviors for consecutive calls to the same method. ```csharp using Moq; using System; public interface IRetryService { bool Connect(); string GetNextItem(); } var mock = new Mock(); // Setup sequence of return values mock.SetupSequence(svc => svc.GetNextItem()) .Returns("First") .Returns("Second") .Returns("Third") .Throws(new InvalidOperationException("No more items")); // Setup sequence with mixed behaviors (success after retries) mock.SetupSequence(svc => svc.Connect()) .Returns(false) // 1st call fails .Returns(false) // 2nd call fails .Throws() // 3rd call throws .Returns(true); // 4th call succeeds // Usage var service = mock.Object; string item1 = service.GetNextItem(); // Returns "First" string item2 = service.GetNextItem(); // Returns "Second" string item3 = service.GetNextItem(); // Returns "Third" // service.GetNextItem(); // Throws InvalidOperationException bool conn1 = service.Connect(); // Returns false bool conn2 = service.Connect(); // Returns false // service.Connect(); // Throws TimeoutException // bool conn4 = service.Connect(); // Returns true (after handling exception) ``` ## Throwing Exceptions Use `Throws()` or `ThrowsAsync()` to configure methods to throw exceptions when invoked. ```csharp using Moq; using System; using System.Threading.Tasks; public interface IFileService { string ReadFile(string path); Task ReadFileAsync(string path); void DeleteFile(string path); } var mock = new Mock(); // Throw specific exception instance mock.Setup(svc => svc.ReadFile("")) .Throws(new ArgumentException("Path cannot be empty", "path")); // Throw exception type mock.Setup(svc => svc.ReadFile("protected.txt")) .Throws(); // Throw based on argument condition mock.Setup(svc => svc.ReadFile(It.Is(p => p.StartsWith("invalid")))) .Throws(); // Async exception throwing mock.Setup(svc => svc.ReadFileAsync("missing.txt")) .ThrowsAsync(new FileNotFoundException("File not found")); // Throw for void methods mock.Setup(svc => svc.DeleteFile("readonly.txt")) .Throws(); // Usage var fileService = mock.Object; Assert.Throws(() => fileService.ReadFile("")); Assert.Throws(() => fileService.ReadFile("protected.txt")); await Assert.ThrowsAsync(() => fileService.ReadFileAsync("missing.txt")); ``` ## Verification Use `Verify()`, `VerifyGet()`, `VerifySet()`, and `VerifyNoOtherCalls()` to assert that expected interactions occurred on the mock. ```csharp using Moq; public interface INotificationService { void SendNotification(string userId, string message); void SendBulkNotification(string[] userIds, string message); int NotificationCount { get; } } var mock = new Mock(); var service = mock.Object; // Execute code under test service.SendNotification("user1", "Hello"); service.SendNotification("user2", "Welcome"); service.SendBulkNotification(new[] { "user3", "user4" }, "Announcement"); var count = service.NotificationCount; // Verify method was called (at least once by default) mock.Verify(svc => svc.SendNotification("user1", "Hello")); // Verify with specific Times constraint mock.Verify(svc => svc.SendNotification(It.IsAny(), It.IsAny()), Times.Exactly(2)); // Verify method was never called mock.Verify(svc => svc.SendNotification("user999", It.IsAny()), Times.Never()); // Verify with custom error message mock.Verify(svc => svc.SendBulkNotification(It.IsAny(), It.IsAny()), Times.Once(), "Bulk notification should be sent exactly once"); // Verify property getter was accessed mock.VerifyGet(svc => svc.NotificationCount, Times.Once()); // Verify no unexpected calls were made mock.VerifyNoOtherCalls(); // Times options: Never(), Once(), AtLeastOnce(), AtMost(n), AtLeast(n), Exactly(n), Between(min, max) ``` ## Events - Raising and Setup Use `Raise()` to trigger events on mocks and `SetupAdd()`/`SetupRemove()` to track event subscriptions. Events can also be raised automatically using `Raises()`. ```csharp using Moq; using System; public interface IButton { event EventHandler Clicked; event EventHandler CustomEvent; void Press(); } public class CustomEventArgs : EventArgs { public string Data { get; set; } } var mock = new Mock(); var eventRaised = false; var receivedData = ""; // Subscribe to the event mock.Object.Clicked += (sender, args) => eventRaised = true; mock.Object.CustomEvent += (sender, args) => receivedData = args.Data; // Manually raise the event mock.Raise(btn => btn.Clicked += null, EventArgs.Empty); // eventRaised is now true // Raise event with custom args mock.Raise(btn => btn.CustomEvent += null, new CustomEventArgs { Data = "test" }); // receivedData is now "test" // Auto-raise event when method is called mock.Setup(btn => btn.Press()) .Raises(btn => btn.Clicked += null, EventArgs.Empty); // Verify event subscription (Moq 4.13+) mock.SetupAdd(btn => btn.Clicked += It.IsAny()) .Verifiable(); mock.SetupRemove(btn => btn.Clicked -= It.IsAny()) .Verifiable(); ``` ## Out and Ref Parameters Moq supports out and ref parameters in method setups, including matching any ref value with `It.Ref.IsAny`. ```csharp using Moq; public interface IParser { bool TryParse(string input, out int result); bool TryParseWithRef(ref string input, out int result); void ModifyValue(ref int value); } var mock = new Mock(); // Setup out parameter var outValue = 42; mock.Setup(p => p.TryParse("42", out outValue)) .Returns(true); // Setup with any ref parameter (Moq 4.8+) mock.Setup(p => p.ModifyValue(ref It.Ref.IsAny)) .Callback(new ModifyValueCallback((ref int v) => v *= 2)); // Delegate for ref callback delegate void ModifyValueCallback(ref int value); // Setup with specific ref instance var refString = "test"; mock.Setup(p => p.TryParseWithRef(ref refString, out outValue)) .Returns(true); // Usage var parser = mock.Object; int result; bool success = parser.TryParse("42", out result); // success=true, result=42 int myValue = 10; parser.ModifyValue(ref myValue); // myValue becomes 20 ``` ## LINQ to Mocks with Mock.Of Use `Mock.Of()` for declarative mock creation with a query-like syntax. Retrieve the underlying mock with `Mock.Get()`. ```csharp using Moq; public interface IOrderService { IOrder CurrentOrder { get; } bool IsProcessing { get; } } public interface IOrder { int Id { get; } decimal Total { get; } ICustomer Customer { get; } } public interface ICustomer { string Name { get; } string Email { get; } } // Create mock with inline setup using LINQ syntax var orderService = Mock.Of(svc => svc.IsProcessing == false && svc.CurrentOrder.Id == 1001 && svc.CurrentOrder.Total == 99.99m && svc.CurrentOrder.Customer.Name == "John Doe" && svc.CurrentOrder.Customer.Email == "john@example.com" ); // Usage - no need to call .Object, it's already the mocked instance bool processing = orderService.IsProcessing; // Returns false int orderId = orderService.CurrentOrder.Id; // Returns 1001 string customerName = orderService.CurrentOrder.Customer.Name; // Returns "John Doe" // Get the underlying Mock for additional setup or verification var mock = Mock.Get(orderService); mock.Verify(svc => svc.CurrentOrder, Times.AtLeastOnce()); // Get nested mock for additional setup var orderMock = Mock.Get(orderService.CurrentOrder); orderMock.Setup(o => o.Total).Returns(149.99m); ``` ## Mock Repository Use `MockRepository` to centralize mock creation and verification with consistent settings across multiple mocks. ```csharp using Moq; public interface IUserRepository { User GetById(int id); } public interface IEmailService { void Send(string to, string message); } public interface ILogger { void Log(string message); } public class User { public int Id; public string Email; } // Create repository with shared settings var repository = new MockRepository(MockBehavior.Strict) { DefaultValue = DefaultValue.Mock }; // Create mocks through the repository var userRepoMock = repository.Create(); var emailMock = repository.Create(); var loggerMock = repository.Create(MockBehavior.Loose); // Override behavior // Setup mocks userRepoMock.Setup(r => r.GetById(1)) .Returns(new User { Id = 1, Email = "user@test.com" }); emailMock.Setup(e => e.Send(It.IsAny(), It.IsAny())); loggerMock.Setup(l => l.Log(It.IsAny())); // Use mocks in test var user = userRepoMock.Object.GetById(1); emailMock.Object.Send(user.Email, "Welcome!"); loggerMock.Object.Log("Email sent"); // Verify all mocks in repository at once repository.Verify(); // Verify all mocks including non-verifiable setups repository.VerifyAll(); ``` ## Mocking Protected Members Use the `Protected()` extension with string-based member names, or use `Protected().As()` for type-safe setup of protected members. ```csharp using Moq; using Moq.Protected; public abstract class DataProcessor { public string Process(string input) { var validated = ValidateInput(input); return Transform(validated); } protected abstract bool ValidateInput(string input); protected abstract string Transform(string input); } var mock = new Mock(); // String-based setup (less type-safe) mock.Protected() .Setup("ValidateInput", ItExpr.IsAny()) .Returns(true); mock.Protected() .Setup("Transform", ItExpr.Is(s => s.Length > 0)) .Returns((string s) => s.ToUpper()); // Type-safe setup using duck-typed interface (Moq 4.8+) public interface IDataProcessorProtected { bool ValidateInput(string input); string Transform(string input); } mock.Protected() .As() .Setup(p => p.ValidateInput(It.IsAny())) .Returns(true); mock.Protected() .As() .Setup(p => p.Transform(It.IsAny())) .Returns((string s) => s.ToUpper()); // Usage var processor = mock.Object; string result = processor.Process("hello"); // Returns "HELLO" // Verification mock.Protected() .Verify("ValidateInput", Times.Once(), ItExpr.IsAny()); ``` ## Implementing Multiple Interfaces with As Use `As()` to add additional interface implementations to a mock, allowing a single mock to satisfy multiple dependencies. ```csharp using Moq; using System; public interface IRepository { object GetById(int id); } public interface IDisposable { void Dispose(); } public interface IUnitOfWork { void Commit(); void Rollback(); } var mock = new Mock(); // Setup primary interface mock.Setup(r => r.GetById(It.IsAny())) .Returns(new object()); // Add IDisposable implementation mock.As() .Setup(d => d.Dispose()); // Add IUnitOfWork implementation var unitOfWork = mock.As(); unitOfWork.Setup(u => u.Commit()); unitOfWork.Setup(u => u.Rollback()); // Single mock object implements all interfaces var repository = mock.Object; var disposable = mock.Object as IDisposable; var uow = mock.Object as IUnitOfWork; // Use the interfaces repository.GetById(1); uow.Commit(); disposable.Dispose(); // Verify across interfaces mock.Verify(r => r.GetById(It.IsAny()), Times.Once()); mock.As().Verify(u => u.Commit(), Times.Once()); ``` ## Resetting Mocks Use `Reset()` to clear all setups, invocations, and event handlers, allowing mock reuse between tests. ```csharp using Moq; public interface ICache { string Get(string key); void Set(string key, string value); } var mock = new Mock(); // Initial setup mock.Setup(c => c.Get("key1")).Returns("value1"); mock.Object.Get("key1"); mock.Object.Set("key1", "new-value"); // Verify some calls were made mock.Verify(c => c.Get("key1"), Times.Once()); mock.Verify(c => c.Set("key1", "new-value"), Times.Once()); // Reset the mock - clears setups, invocations, and event handlers mock.Reset(); // Now verification fails because invocation history is cleared // mock.Verify(c => c.Get("key1"), Times.Once()); // Would throw // Previous setup is also cleared string result = mock.Object.Get("key1"); // Returns null (default) // Create new setup for next test mock.Setup(c => c.Get("key2")).Returns("value2"); ``` ## Summary Moq is primarily used in unit testing scenarios where developers need to isolate code under test from its dependencies. Common use cases include mocking data access layers (repositories, database contexts), external services (HTTP clients, email services, payment gateways), logging frameworks, configuration providers, and any interface-based dependency. The library excels at creating lightweight test doubles that can simulate both successful and error conditions without involving real infrastructure. Integration with Moq follows the Arrange-Act-Assert pattern common in unit testing. In the Arrange phase, create mocks using `new Mock()` or `Mock.Of()`, configure behavior with `Setup()`, and inject the mock objects (via `mock.Object`) into the system under test. During the Act phase, execute the code being tested. In the Assert phase, use `Verify()` methods to confirm expected interactions occurred. Moq integrates seamlessly with all major .NET test frameworks including xUnit, NUnit, and MSTest, requiring only a NuGet package reference (`Install-Package Moq`) to get started.