Table of Contents

Real-World Examples & Case Studies

This guide provides practical examples of using SMock in real-world scenarios, including complete case studies from actual development projects.

Table of Contents

Enterprise Application Testing

Case Study: Financial Trading System

Background: A financial trading system needed comprehensive testing of risk calculation modules that depend on external market data feeds and regulatory compliance checks.

Challenge: The system made extensive use of static methods for:

  • Real-time market data retrieval
  • Risk calculation utilities
  • Compliance validation
  • Audit logging

Solution with SMock:

[TestFixture]
public class TradingSystemTests
{
    [Test]
    public void Calculate_Portfolio_Risk_Under_Market_Stress()
    {
        // Arrange: Mock market data for stress testing
        var stressTestData = new MarketData
        {
            SP500 = 3000,      // 30% drop
            VIX = 45,          // High volatility
            TreasuryYield = 0.5m,
            LastUpdated = new DateTime(2024, 1, 15, 9, 30, 0)
        };

        using var marketDataMock = Mock.Setup(() =>
            MarketDataProvider.GetCurrentData())
            .Returns(stressTestData);

        using var timeMock = Mock.Setup(() => DateTime.Now)
            .Returns(new DateTime(2024, 1, 15, 9, 30, 0));

        // Mock compliance rules for stress scenario
        using var complianceMock = Mock.Setup(context =>
            ComplianceValidator.ValidateRiskLimits(context.It.IsAny<decimal>()))
            .Returns<decimal>(risk => new ComplianceResult
            {
                IsValid = risk <= 0.15m, // 15% max risk in stress conditions
                Violations = risk > 0.15m ? new[] { "Exceeds stress test limits" } : new string[0]
            });

        // Mock audit logging to verify risk calculations are logged
        var auditEntries = new List<AuditEntry>();
        using var auditMock = Mock.Setup(context =>
            AuditLogger.LogRiskCalculation(context.It.IsAny<string>(), context.It.IsAny<decimal>(), context.It.IsAny<DateTime>()))
            .Callback<string, decimal, DateTime>((portfolioId, risk, timestamp) =>
                auditEntries.Add(new AuditEntry
                {
                    PortfolioId = portfolioId,
                    CalculatedRisk = risk,
                    Timestamp = timestamp
                }));

        // Act: Calculate risk for a test portfolio
        var portfolio = new Portfolio
        {
            Id = "TEST_PORTFOLIO_001",
            Positions = new[]
            {
                new Position { Symbol = "AAPL", Shares = 1000, Beta = 1.2m },
                new Position { Symbol = "GOOGL", Shares = 500, Beta = 1.1m },
                new Position { Symbol = "MSFT", Shares = 750, Beta = 0.9m }
            }
        };

        var riskCalculator = new PortfolioRiskCalculator();
        var riskReport = riskCalculator.CalculateRisk(portfolio);

        // Assert: Verify risk calculation and compliance
        Assert.IsNotNull(riskReport);
        Assert.Greater(riskReport.VaR, 0, "Value at Risk should be positive in stress scenario");
        Assert.Less(riskReport.VaR, 0.20m, "VaR should not exceed 20% even in stress conditions");

        // Verify compliance check was performed
        Assert.IsNotNull(riskReport.ComplianceStatus);
        Assert.AreEqual(riskReport.VaR <= 0.15m, riskReport.ComplianceStatus.IsValid);

        // Verify audit trail
        Assert.AreEqual(1, auditEntries.Count);
        Assert.AreEqual("TEST_PORTFOLIO_001", auditEntries[0].PortfolioId);
        Assert.AreEqual(riskReport.VaR, auditEntries[0].CalculatedRisk);
    }

    [Test]
    public void Validate_Trading_Hours_And_Market_Status()
    {
        // Test different market conditions and trading hours
        var testScenarios = new[]
        {
            new { Time = new DateTime(2024, 1, 15, 9, 30, 0), IsOpen = true, Session = "Regular" },
            new { Time = new DateTime(2024, 1, 15, 16, 0, 0), IsOpen = false, Session = "Closed" },
            new { Time = new DateTime(2024, 1, 15, 4, 0, 0), IsOpen = true, Session = "PreMarket" },
            new { Time = new DateTime(2024, 1, 13, 10, 0, 0), IsOpen = false, Session = "Weekend" } // Saturday
        };

        foreach (var scenario in testScenarios)
        {
            using var timeMock = Mock.Setup(() => DateTime.Now)
                .Returns(scenario.Time);

            using var marketStatusMock = Mock.Setup(() =>
                MarketStatusProvider.GetCurrentStatus())
                .Returns(new MarketStatus
                {
                    IsOpen = scenario.IsOpen,
                    CurrentSession = scenario.Session,
                    NextOpenTime = scenario.IsOpen ? (DateTime?)null : GetNextMarketOpen(scenario.Time)
                });

            var tradingEngine = new TradingEngine();
            var canTrade = tradingEngine.CanExecuteTrade();

            Assert.AreEqual(scenario.IsOpen, canTrade,
                $"Trading should be {(scenario.IsOpen ? "allowed" : "blocked")} during {scenario.Session} at {scenario.Time}");
        }
    }

    private DateTime GetNextMarketOpen(DateTime currentTime)
    {
        // Logic to calculate next market opening time
        if (currentTime.DayOfWeek == DayOfWeek.Saturday)
            return currentTime.AddDays(2).Date.AddHours(9.5); // Monday 9:30 AM
        if (currentTime.DayOfWeek == DayOfWeek.Sunday)
            return currentTime.AddDays(1).Date.AddHours(9.5); // Monday 9:30 AM
        if (currentTime.TimeOfDay > new TimeSpan(16, 0, 0))
            return currentTime.AddDays(1).Date.AddHours(9.5); // Next day 9:30 AM
        return currentTime.Date.AddHours(9.5); // Today 9:30 AM
    }
}

Results: The SMock-based testing approach enabled comprehensive testing of the trading system's risk calculations across various market conditions, reducing production incidents by 75% and ensuring regulatory compliance.

Legacy Code Modernization

Case Study: Modernizing a 15-Year-Old Inventory Management System

Background: A manufacturing company needed to modernize their inventory management system that was heavily dependent on static utility classes and file-based configuration.

Challenge: The legacy code had:

  • Deeply nested static method calls
  • File system dependencies for configuration
  • Hard-coded paths and system dependencies
  • No existing unit tests

SMock-Enabled Modernization Strategy:

// Legacy code structure (simplified)
public class LegacyInventoryManager
{
    public InventoryReport GenerateReport(DateTime reportDate)
    {
        // Legacy code with multiple static dependencies
        var configPath = SystemPaths.GetConfigDirectory();
        var config = FileHelper.ReadConfig(Path.Combine(configPath, "inventory.config"));
        var dbConnection = DatabaseFactory.CreateConnection(config.ConnectionString);

        var warehouseData = DatabaseQueryHelper.ExecuteQuery(
            dbConnection,
            SqlQueryBuilder.BuildWarehouseQuery(reportDate)
        );

        var report = ReportFormatter.FormatInventoryData(warehouseData);

        AuditLogger.LogReportGeneration("Inventory", reportDate, Environment.UserName);

        return report;
    }
}

// Modern test-enabled version with SMock
[TestFixture]
public class ModernizedInventoryManagerTests
{
    [Test]
    public void Generate_Inventory_Report_Success_Scenario()
    {
        // Arrange: Mock the complex legacy dependencies
        var testDate = new DateTime(2024, 1, 15);
        var testUser = "TestUser";
        var testConfig = new InventoryConfig
        {
            ConnectionString = "Server=localhost;Database=TestInventory;",
            WarehouseLocations = new[] { "WH001", "WH002", "WH003" },
            ReportFormats = new[] { "Summary", "Detailed" }
        };

        using var pathMock = Mock.Setup(() => SystemPaths.GetConfigDirectory())
            .Returns(@"C:\TestConfig");

        using var fileMock = Mock.Setup(() =>
            FileHelper.ReadConfig(@"C:\TestConfig\inventory.config"))
            .Returns(testConfig);

        using var dbFactoryMock = Mock.Setup(() =>
            DatabaseFactory.CreateConnection(testConfig.ConnectionString))
            .Returns(new MockDbConnection { IsConnected = true });

        using var queryBuilderMock = Mock.Setup(() =>
            SqlQueryBuilder.BuildWarehouseQuery(testDate))
            .Returns("SELECT * FROM Inventory WHERE ReportDate = '2024-01-15'");

        var mockWarehouseData = new[]
        {
            new WarehouseItem { Location = "WH001", ItemCode = "ITEM001", Quantity = 150 },
            new WarehouseItem { Location = "WH002", ItemCode = "ITEM002", Quantity = 200 },
            new WarehouseItem { Location = "WH003", ItemCode = "ITEM003", Quantity = 75 }
        };

        using var queryMock = Mock.Setup(context =>
            DatabaseQueryHelper.ExecuteQuery(context.It.IsAny<IDbConnection>(), context.It.IsAny<string>()))
            .Returns(mockWarehouseData);

        using var formatterMock = Mock.Setup(() =>
            ReportFormatter.FormatInventoryData(mockWarehouseData))
            .Returns(new InventoryReport
            {
                ReportDate = testDate,
                TotalItems = 3,
                TotalQuantity = 425,
                WarehouseBreakdown = mockWarehouseData.GroupBy(w => w.Location)
                    .ToDictionary(g => g.Key, g => g.Sum(w => w.Quantity))
            });

        using var userMock = Mock.Setup(() => Environment.UserName)
            .Returns(testUser);

        var auditEntries = new List<AuditLogEntry>();
        using var auditMock = Mock.Setup(context =>
            AuditLogger.LogReportGeneration(context.It.IsAny<string>(), context.It.IsAny<DateTime>(), context.It.IsAny<string>()))
            .Callback<string, DateTime, string>((reportType, date, user) =>
                auditEntries.Add(new AuditLogEntry
                {
                    ReportType = reportType,
                    GenerationDate = date,
                    User = user,
                    Timestamp = DateTime.Now
                }));

        // Act: Generate the report using the legacy system
        var inventoryManager = new LegacyInventoryManager();
        var report = inventoryManager.GenerateReport(testDate);

        // Assert: Verify the report and all interactions
        Assert.IsNotNull(report);
        Assert.AreEqual(testDate, report.ReportDate);
        Assert.AreEqual(3, report.TotalItems);
        Assert.AreEqual(425, report.TotalQuantity);

        // Verify warehouse breakdown
        Assert.AreEqual(150, report.WarehouseBreakdown["WH001"]);
        Assert.AreEqual(200, report.WarehouseBreakdown["WH002"]);
        Assert.AreEqual(75, report.WarehouseBreakdown["WH003"]);

        // Verify audit logging
        Assert.AreEqual(1, auditEntries.Count);
        Assert.AreEqual("Inventory", auditEntries[0].ReportType);
        Assert.AreEqual(testDate, auditEntries[0].GenerationDate);
        Assert.AreEqual(testUser, auditEntries[0].User);
    }

    [Test]
    public void Handle_Database_Connection_Failure_Gracefully()
    {
        // Arrange: Simulate database connection failure
        var testDate = new DateTime(2024, 1, 15);

        using var pathMock = Mock.Setup(() => SystemPaths.GetConfigDirectory())
            .Returns(@"C:\TestConfig");

        using var fileMock = Mock.Setup(context =>
            FileHelper.ReadConfig(context.It.IsAny<string>()))
            .Returns(new InventoryConfig { ConnectionString = "invalid_connection" });

        // Mock database connection failure
        using var dbFailureMock = Mock.Setup(() =>
            DatabaseFactory.CreateConnection("invalid_connection"))
            .Throws<DatabaseConnectionException>();

        var inventoryManager = new LegacyInventoryManager();

        // Act & Assert: Verify graceful failure handling
        var exception = Assert.Throws<DatabaseConnectionException>(
            () => inventoryManager.GenerateReport(testDate));

        Assert.IsNotNull(exception);
        // Verify that the system fails fast and doesn't attempt further operations
    }

    [Test]
    public void Validate_Configuration_File_Processing()
    {
        // Test various configuration scenarios
        var configScenarios = new[]
        {
            new { Scenario = "Missing config file", ShouldThrow = true, Config = (InventoryConfig)null },
            new { Scenario = "Empty connection string", ShouldThrow = true, Config = new InventoryConfig { ConnectionString = "" } },
            new { Scenario = "No warehouse locations", ShouldThrow = false, Config = new InventoryConfig { ConnectionString = "valid", WarehouseLocations = new string[0] } },
            new { Scenario = "Valid configuration", ShouldThrow = false, Config = new InventoryConfig { ConnectionString = "valid", WarehouseLocations = new[] { "WH001" } } }
        };

        foreach (var scenario in configScenarios)
        {
            using var pathMock = Mock.Setup(() => SystemPaths.GetConfigDirectory())
                .Returns(@"C:\TestConfig");

            if (scenario.Config == null)
            {
                using var fileMock = Mock.Setup(context =>
                    FileHelper.ReadConfig(context.It.IsAny<string>()))
                    .Throws<FileNotFoundException>();
            }
            else
            {
                using var fileMock = Mock.Setup(context =>
                    FileHelper.ReadConfig(context.It.IsAny<string>()))
                    .Returns(scenario.Config);

                if (!string.IsNullOrEmpty(scenario.Config.ConnectionString))
                {
                    using var dbMock = Mock.Setup(() =>
                        DatabaseFactory.CreateConnection(scenario.Config.ConnectionString))
                        .Returns(new MockDbConnection { IsConnected = true });
                }
            }

            var inventoryManager = new LegacyInventoryManager();

            if (scenario.ShouldThrow)
            {
                Assert.Throws<Exception>(() =>
                    inventoryManager.GenerateReport(new DateTime(2024, 1, 15)),
                    $"Scenario '{scenario.Scenario}' should throw an exception");
            }
            else
            {
                // Additional mocks needed for successful scenarios
                using var queryBuilderMock = Mock.Setup(context =>
                    SqlQueryBuilder.BuildWarehouseQuery(context.It.IsAny<DateTime>()))
                    .Returns("SELECT * FROM Inventory");

                using var queryMock = Mock.Setup(context =>
                    DatabaseQueryHelper.ExecuteQuery(context.It.IsAny<IDbConnection>(), context.It.IsAny<string>()))
                    .Returns(new WarehouseItem[0]);

                using var formatterMock = Mock.Setup(context =>
                    ReportFormatter.FormatInventoryData(context.It.IsAny<WarehouseItem[]>()))
                    .Returns(new InventoryReport
                    {
                        ReportDate = new DateTime(2024, 1, 15),
                        TotalItems = 0,
                        TotalQuantity = 0
                    });

                using var auditMock = Mock.Setup(context =>
                    AuditLogger.LogReportGeneration(context.It.IsAny<string>(), context.It.IsAny<DateTime>(), context.It.IsAny<string>()));

                Assert.DoesNotThrow(() =>
                    inventoryManager.GenerateReport(new DateTime(2024, 1, 15)),
                    $"Scenario '{scenario.Scenario}' should not throw an exception");
            }
        }
    }
}

Results: The modernization project was completed 40% faster than estimated due to SMock enabling comprehensive testing of the legacy code without modification. This allowed for confident refactoring and gradual modernization.

Web API Testing

Case Study: E-commerce API with External Dependencies

Background: An e-commerce platform's order processing API needed thorough testing of payment processing, inventory management, and shipping calculations.

[TestFixture]
public class OrderProcessingApiTests
{
    [Test]
    public async Task Process_Order_Complete_Success_Flow()
    {
        // Arrange: Set up comprehensive mocking for order processing
        var testOrder = new OrderRequest
        {
            CustomerId = "CUST_12345",
            Items = new[]
            {
                new OrderItem { ProductId = "PROD_001", Quantity = 2, Price = 29.99m },
                new OrderItem { ProductId = "PROD_002", Quantity = 1, Price = 49.99m }
            },
            ShippingAddress = new Address
            {
                Street = "123 Test St",
                City = "Test City",
                State = "TS",
                ZipCode = "12345",
                Country = "US"
            },
            PaymentMethod = new PaymentMethod
            {
                Type = "CreditCard",
                Token = "tok_test_12345"
            }
        };

        // Mock inventory checks
        using var inventoryMock = Mock.Setup(context =>
            InventoryService.CheckAvailability(context.It.IsAny<string>(), context.It.IsAny<int>()))
            .Returns<string, int>((productId, quantity) => new InventoryResult
            {
                ProductId = productId,
                Available = true,
                StockLevel = quantity + 10 // Always have more than requested
            });

        // Mock pricing service
        using var pricingMock = Mock.Setup(context =>
            PricingService.CalculateTotal(context.It.IsAny<OrderItem[]>()))
            .Returns(new PricingResult
            {
                Subtotal = 109.97m,
                Tax = 8.80m,
                Total = 118.77m
            });

        // Mock shipping calculation
        using var shippingMock = Mock.Setup(context =>
            ShippingCalculator.CalculateShipping(context.It.IsAny<Address>(), context.It.IsAny<decimal>()))
            .Returns(new ShippingResult
            {
                Cost = 9.99m,
                EstimatedDays = 3,
                Method = "Standard"
            });

        // Mock payment processing
        using var paymentMock = Mock.Setup(context =>
            PaymentProcessor.ProcessPayment(context.It.IsAny<PaymentMethod>(), context.It.IsAny<decimal>()))
            .Returns(Task.FromResult(new PaymentResult
            {
                Success = true,
                TransactionId = "TXN_789012",
                AuthorizationCode = "AUTH_345678"
            }));

        // Mock order persistence
        var savedOrders = new List<Order>();
        using var orderSaveMock = Mock.Setup(context =>
            OrderRepository.SaveOrder(context.It.IsAny<Order>()))
            .Callback<Order>(order => savedOrders.Add(order))
            .Returns(Task.FromResult("ORD_" + Guid.NewGuid().ToString("N")[..8].ToUpper()));

        // Mock notification service
        var sentNotifications = new List<NotificationRequest>();
        using var notificationMock = Mock.Setup(context =>
            NotificationService.SendOrderConfirmation(context.It.IsAny<string>(), context.It.IsAny<string>()))
            .Callback<string, string>((customerId, orderId) =>
                sentNotifications.Add(new NotificationRequest
                {
                    CustomerId = customerId,
                    OrderId = orderId,
                    Type = "OrderConfirmation"
                }))
            .Returns(Task.CompletedTask);

        // Mock audit logging
        var auditLogs = new List<AuditLog>();
        using var auditMock = Mock.Setup(context =>
            AuditLogger.LogOrderProcessing(context.It.IsAny<string>(), context.It.IsAny<string>(), context.It.IsAny<decimal>()))
            .Callback<string, string, decimal>((orderId, customerId, amount) =>
                auditLogs.Add(new AuditLog
                {
                    OrderId = orderId,
                    CustomerId = customerId,
                    Amount = amount,
                    Action = "OrderProcessed",
                    Timestamp = DateTime.UtcNow
                }));

        // Act: Process the order
        var orderProcessor = new OrderProcessor();
        var result = await orderProcessor.ProcessOrderAsync(testOrder);

        // Assert: Verify complete order processing
        Assert.IsNotNull(result);
        Assert.IsTrue(result.Success);
        Assert.IsNotNull(result.OrderId);
        Assert.AreEqual("TXN_789012", result.TransactionId);

        // Verify order was saved correctly
        Assert.AreEqual(1, savedOrders.Count);
        var savedOrder = savedOrders[0];
        Assert.AreEqual(testOrder.CustomerId, savedOrder.CustomerId);
        Assert.AreEqual(2, savedOrder.Items.Count);
        Assert.AreEqual(118.77m + 9.99m, savedOrder.Total); // Total + Shipping

        // Verify notification was sent
        Assert.AreEqual(1, sentNotifications.Count);
        Assert.AreEqual(testOrder.CustomerId, sentNotifications[0].CustomerId);

        // Verify audit logging
        Assert.AreEqual(1, auditLogs.Count);
        Assert.AreEqual(testOrder.CustomerId, auditLogs[0].CustomerId);
        Assert.AreEqual(savedOrder.Total, auditLogs[0].Amount);
    }

    [Test]
    public async Task Handle_Payment_Failure_Gracefully()
    {
        // Arrange: Set up scenario where payment fails
        var testOrder = CreateBasicOrderRequest();

        // Set up successful mocks for everything except payment
        SetupSuccessfulInventoryAndPricing();

        // Mock payment failure
        using var paymentMock = Mock.Setup(context =>
            PaymentProcessor.ProcessPayment(context.It.IsAny<PaymentMethod>(), context.It.IsAny<decimal>()))
            .Returns(Task.FromResult(new PaymentResult
            {
                Success = false,
                ErrorCode = "DECLINED",
                ErrorMessage = "Insufficient funds"
            }));

        // Mock inventory rollback
        var rollbackCalls = new List<InventoryRollbackRequest>();
        using var rollbackMock = Mock.Setup(context =>
            InventoryService.RollbackReservation(context.It.IsAny<string>(), context.It.IsAny<int>()))
            .Callback<string, int>((productId, quantity) =>
                rollbackCalls.Add(new InventoryRollbackRequest
                {
                    ProductId = productId,
                    Quantity = quantity
                }));

        // Ensure no order is saved on failure
        using var orderSaveMock = Mock.Setup(context =>
            OrderRepository.SaveOrder(context.It.IsAny<Order>()))
            .Throws(new InvalidOperationException("Order should not be saved on payment failure"));

        // Act: Process order with failing payment
        var orderProcessor = new OrderProcessor();
        var result = await orderProcessor.ProcessOrderAsync(testOrder);

        // Assert: Verify failure handling
        Assert.IsNotNull(result);
        Assert.IsFalse(result.Success);
        Assert.AreEqual("DECLINED", result.ErrorCode);
        Assert.AreEqual("Insufficient funds", result.ErrorMessage);

        // Verify inventory was rolled back
        Assert.AreEqual(2, rollbackCalls.Count); // One for each item
        Assert.IsTrue(rollbackCalls.Any(r => r.ProductId == "PROD_001" && r.Quantity == 2));
        Assert.IsTrue(rollbackCalls.Any(r => r.ProductId == "PROD_002" && r.Quantity == 1));
    }

    [Test]
    public async Task Handle_Inventory_Shortage_Properly()
    {
        // Arrange: Set up scenario with insufficient inventory
        var testOrder = CreateBasicOrderRequest();

        // Mock partial inventory availability
        using var inventoryMock = Mock.Setup(context =>
            InventoryService.CheckAvailability(context.It.IsAny<string>(), context.It.IsAny<int>()))
            .Returns<string, int>((productId, quantity) =>
            {
                if (productId == "PROD_001")
                    return new InventoryResult { ProductId = productId, Available = true, StockLevel = quantity };
                else
                    return new InventoryResult { ProductId = productId, Available = false, StockLevel = 0 };
            });

        // Act: Process order with inventory shortage
        var orderProcessor = new OrderProcessor();
        var result = await orderProcessor.ProcessOrderAsync(testOrder);

        // Assert: Verify proper handling of inventory shortage
        Assert.IsNotNull(result);
        Assert.IsFalse(result.Success);
        Assert.AreEqual("INVENTORY_INSUFFICIENT", result.ErrorCode);
        Assert.Contains("PROD_002", result.ErrorMessage);
    }

    private OrderRequest CreateBasicOrderRequest()
    {
        return new OrderRequest
        {
            CustomerId = "CUST_12345",
            Items = new[]
            {
                new OrderItem { ProductId = "PROD_001", Quantity = 2, Price = 29.99m },
                new OrderItem { ProductId = "PROD_002", Quantity = 1, Price = 49.99m }
            },
            ShippingAddress = new Address
            {
                Street = "123 Test St",
                City = "Test City",
                State = "TS",
                ZipCode = "12345",
                Country = "US"
            },
            PaymentMethod = new PaymentMethod
            {
                Type = "CreditCard",
                Token = "tok_test_12345"
            }
        };
    }

    private void SetupSuccessfulInventoryAndPricing()
    {
        Mock.Setup(context => InventoryService.CheckAvailability(context.It.IsAny<string>(), context.It.IsAny<int>()))
            .Returns<string, int>((productId, quantity) => new InventoryResult
            {
                ProductId = productId,
                Available = true,
                StockLevel = quantity + 10
            });

        Mock.Setup(context => PricingService.CalculateTotal(context.It.IsAny<OrderItem[]>()))
            .Returns(new PricingResult { Subtotal = 109.97m, Tax = 8.80m, Total = 118.77m });

        Mock.Setup(context => ShippingCalculator.CalculateShipping(context.It.IsAny<Address>(), context.It.IsAny<decimal>()))
            .Returns(new ShippingResult { Cost = 9.99m, EstimatedDays = 3, Method = "Standard" });
    }
}

File System Integration

Case Study: Document Management System

[TestFixture]
public class DocumentManagementSystemTests
{
    [Test]
    public void Upload_Document_With_Virus_Scanning_And_Metadata_Extraction()
    {
        // Arrange: Complex document processing pipeline
        var testDocument = new DocumentUploadRequest
        {
            FileName = "important_contract.pdf",
            Content = Convert.FromBase64String("JVBERi0xLjQKJcOkw7zDt..."), // Mock PDF content
            UserId = "USER_12345",
            Category = "Contracts"
        };

        var expectedPath = Path.Combine(@"C:\Documents\Contracts\2024\01", "important_contract.pdf");

        // Mock file system operations
        using var directoryExistsMock = Mock.Setup(() =>
            Directory.Exists(Path.GetDirectoryName(expectedPath)))
            .Returns(false);

        using var directoryCreateMock = Mock.Setup(() =>
            Directory.CreateDirectory(Path.GetDirectoryName(expectedPath)));

        using var fileWriteMock = Mock.Setup(context =>
            File.WriteAllBytes(expectedPath, context.It.IsAny<byte[]>()));

        // Mock virus scanning
        using var virusScanMock = Mock.Setup(() =>
            VirusScanner.ScanFile(expectedPath))
            .Returns(new ScanResult
            {
                IsClean = true,
                ScanDuration = TimeSpan.FromSeconds(2.3),
                Engine = "ClamAV",
                SignatureVersion = "2024.01.15"
            });

        // Mock metadata extraction
        using var metadataExtractionMock = Mock.Setup(() =>
            MetadataExtractor.ExtractMetadata(expectedPath))
            .Returns(new DocumentMetadata
            {
                Title = "Service Agreement Contract",
                Author = "Legal Department",
                CreationDate = new DateTime(2024, 1, 10),
                PageCount = 15,
                FileSize = testDocument.Content.Length,
                MimeType = "application/pdf"
            });

        // Mock thumbnail generation
        using var thumbnailMock = Mock.Setup(context =>
            ThumbnailGenerator.GenerateThumbnail(expectedPath, context.It.IsAny<ThumbnailOptions>()))
            .Returns(new ThumbnailResult
            {
                ThumbnailPath = expectedPath.Replace(".pdf", "_thumb.jpg"),
                Width = 200,
                Height = 260
            });

        // Mock database storage
        var savedDocuments = new List<DocumentRecord>();
        using var dbSaveMock = Mock.Setup(context =>
            DocumentRepository.SaveDocument(context.It.IsAny<DocumentRecord>()))
            .Callback<DocumentRecord>(doc => savedDocuments.Add(doc))
            .Returns(Task.FromResult("DOC_" + Guid.NewGuid().ToString("N")[..8]));

        // Mock audit logging
        var auditEntries = new List<DocumentAuditEntry>();
        using var auditMock = Mock.Setup(context =>
            DocumentAuditLogger.LogDocumentUpload(context.It.IsAny<string>(), context.It.IsAny<string>(), context.It.IsAny<long>()))
            .Callback<string, string, long>((userId, fileName, fileSize) =>
                auditEntries.Add(new DocumentAuditEntry
                {
                    UserId = userId,
                    FileName = fileName,
                    FileSize = fileSize,
                    Action = "Upload",
                    Timestamp = DateTime.UtcNow
                }));

        // Act: Upload the document
        var documentManager = new DocumentManager();
        var result = await documentManager.UploadDocumentAsync(testDocument);

        // Assert: Verify complete upload process
        Assert.IsNotNull(result);
        Assert.IsTrue(result.Success);
        Assert.IsNotNull(result.DocumentId);

        // Verify document was saved to database
        Assert.AreEqual(1, savedDocuments.Count);
        var savedDoc = savedDocuments[0];
        Assert.AreEqual(testDocument.FileName, savedDoc.FileName);
        Assert.AreEqual(testDocument.UserId, savedDoc.UploadedBy);
        Assert.AreEqual(testDocument.Category, savedDoc.Category);
        Assert.AreEqual("Service Agreement Contract", savedDoc.Metadata.Title);
        Assert.AreEqual(15, savedDoc.Metadata.PageCount);

        // Verify audit trail
        Assert.AreEqual(1, auditEntries.Count);
        Assert.AreEqual(testDocument.UserId, auditEntries[0].UserId);
        Assert.AreEqual(testDocument.FileName, auditEntries[0].FileName);
    }

    [Test]
    public void Handle_Virus_Detection_During_Upload()
    {
        // Arrange: Infected file scenario
        var infectedDocument = new DocumentUploadRequest
        {
            FileName = "suspicious_file.exe",
            Content = new byte[] { 0x4D, 0x5A, 0x90, 0x00 }, // PE header
            UserId = "USER_12345",
            Category = "Uploads"
        };

        var tempPath = Path.Combine(Path.GetTempPath(), "suspicious_file.exe");

        // Set up file system mocks
        using var directoryExistsMock = Mock.Setup(context =>
            Directory.Exists(context.It.IsAny<string>())).Returns(true);

        using var fileWriteMock = Mock.Setup(context =>
            File.WriteAllBytes(tempPath, context.It.IsAny<byte[]>()));

        // Mock virus detection
        using var virusScanMock = Mock.Setup(() =>
            VirusScanner.ScanFile(tempPath))
            .Returns(new ScanResult
            {
                IsClean = false,
                ThreatName = "Win32.Malware.Generic",
                ScanDuration = TimeSpan.FromSeconds(1.2)
            });

        // Mock quarantine process
        var quarantinedFiles = new List<QuarantineRecord>();
        using var quarantineMock = Mock.Setup(context =>
            QuarantineManager.QuarantineFile(tempPath, context.It.IsAny<string>()))
            .Callback<string, string>((filePath, threatName) =>
                quarantinedFiles.Add(new QuarantineRecord
                {
                    OriginalPath = filePath,
                    ThreatName = threatName,
                    QuarantineTime = DateTime.UtcNow
                }));

        // Mock file deletion
        using var fileDeleteMock = Mock.Setup(() => File.Delete(tempPath));

        // Mock security incident logging
        var securityIncidents = new List<SecurityIncident>();
        using var securityLogMock = Mock.Setup(context =>
            SecurityLogger.LogVirusDetection(context.It.IsAny<string>(), context.It.IsAny<string>(), context.It.IsAny<string>()))
            .Callback<string, string, string>((userId, fileName, threatName) =>
                securityIncidents.Add(new SecurityIncident
                {
                    UserId = userId,
                    FileName = fileName,
                    ThreatName = threatName,
                    Severity = "High",
                    Timestamp = DateTime.UtcNow
                }));

        // Act: Attempt to upload infected file
        var documentManager = new DocumentManager();
        var result = await documentManager.UploadDocumentAsync(infectedDocument);

        // Assert: Verify security response
        Assert.IsNotNull(result);
        Assert.IsFalse(result.Success);
        Assert.AreEqual("VIRUS_DETECTED", result.ErrorCode);
        Assert.Contains("Win32.Malware.Generic", result.ErrorMessage);

        // Verify file was quarantined
        Assert.AreEqual(1, quarantinedFiles.Count);
        Assert.AreEqual("Win32.Malware.Generic", quarantinedFiles[0].ThreatName);

        // Verify security incident was logged
        Assert.AreEqual(1, securityIncidents.Count);
        Assert.AreEqual(infectedDocument.UserId, securityIncidents[0].UserId);
        Assert.AreEqual("High", securityIncidents[0].Severity);
    }
}

Database Access Layer Testing

Case Study: Multi-Tenant SaaS Application

[TestFixture]
public class MultiTenantDataAccessTests
{
    [Test]
    public void Ensure_Tenant_Isolation_In_Data_Queries()
    {
        // Arrange: Multi-tenant scenario testing
        var tenant1Id = "TENANT_A";
        var tenant2Id = "TENANT_B";
        var currentUser = "USER_123";

        // Mock tenant context
        using var tenantContextMock = Mock.Setup(() =>
            TenantContext.GetCurrentTenantId())
            .Returns(tenant1Id);

        using var userContextMock = Mock.Setup(() =>
            UserContext.GetCurrentUserId())
            .Returns(currentUser);

        // Mock database connection with tenant isolation
        var executedQueries = new List<DatabaseQuery>();
        using var dbQueryMock = Mock.Setup(context =>
            DatabaseExecutor.ExecuteQuery(context.It.IsAny<string>(), context.It.IsAny<object[]>()))
            .Callback<string, object[]>((sql, parameters) =>
                executedQueries.Add(new DatabaseQuery
                {
                    Sql = sql,
                    Parameters = parameters,
                    TenantId = TenantContext.GetCurrentTenantId(),
                    ExecutedAt = DateTime.UtcNow
                }))
            .Returns(new[]
            {
                new Customer { Id = 1, Name = "Customer A1", TenantId = tenant1Id },
                new Customer { Id = 2, Name = "Customer A2", TenantId = tenant1Id }
            });

        // Mock audit logging for data access
        var dataAccessLogs = new List<DataAccessAuditEntry>();
        using var dataAuditMock = Mock.Setup(context =>
            DataAccessAuditor.LogQuery(context.It.IsAny<string>(), context.It.IsAny<string>(), context.It.IsAny<string>()))
            .Callback<string, string, string>((userId, tenantId, operation) =>
                dataAccessLogs.Add(new DataAccessAuditEntry
                {
                    UserId = userId,
                    TenantId = tenantId,
                    Operation = operation,
                    Timestamp = DateTime.UtcNow
                }));

        // Act: Execute tenant-specific query
        var customerRepository = new CustomerRepository();
        var customers = customerRepository.GetActiveCustomers();

        // Assert: Verify tenant isolation
        Assert.IsNotNull(customers);
        Assert.AreEqual(2, customers.Count());
        Assert.IsTrue(customers.All(c => c.TenantId == tenant1Id));

        // Verify query was properly formed with tenant filter
        Assert.AreEqual(1, executedQueries.Count);
        var executedQuery = executedQueries[0];
        Assert.Contains("TenantId = @tenantId", executedQuery.Sql);
        Assert.Contains(tenant1Id, executedQuery.Parameters);

        // Verify data access was audited
        Assert.AreEqual(1, dataAccessLogs.Count);
        Assert.AreEqual(currentUser, dataAccessLogs[0].UserId);
        Assert.AreEqual(tenant1Id, dataAccessLogs[0].TenantId);
        Assert.AreEqual("GetActiveCustomers", dataAccessLogs[0].Operation);
    }

    [Test]
    public void Prevent_Cross_Tenant_Data_Access()
    {
        // Arrange: Attempt to access data from different tenant
        var currentTenantId = "TENANT_A";
        var attemptedCustomerId = 999; // Belongs to TENANT_B

        using var tenantContextMock = Mock.Setup(() =>
            TenantContext.GetCurrentTenantId())
            .Returns(currentTenantId);

        // Mock database query that finds no results (due to tenant filtering)
        using var dbQueryMock = Mock.Setup(context =>
            DatabaseExecutor.ExecuteQuery(context.It.IsAny<string>(), context.It.IsAny<object[]>()))
            .Returns(new Customer[0]); // No results due to tenant isolation

        // Mock security violation logging
        var securityViolations = new List<SecurityViolation>();
        using var securityMock = Mock.Setup(context =>
            SecurityLogger.LogUnauthorizedAccess(context.It.IsAny<string>(), context.It.IsAny<string>(), context.It.IsAny<string>()))
            .Callback<string, string, string>((userId, resource, reason) =>
                securityViolations.Add(new SecurityViolation
                {
                    UserId = userId,
                    AttemptedResource = resource,
                    Reason = reason,
                    Timestamp = DateTime.UtcNow
                }));

        // Act: Attempt to access cross-tenant data
        var customerRepository = new CustomerRepository();
        var customer = customerRepository.GetCustomerById(attemptedCustomerId);

        // Assert: Verify access was denied
        Assert.IsNull(customer);

        // In a production scenario, this might trigger additional security logging
        // if the application detects cross-tenant access attempts
    }
}

This comprehensive guide demonstrates how SMock enables testing of complex, real-world applications with multiple external dependencies, ensuring reliable and maintainable test suites.

Working Real-World Examples

The real-world examples shown in this guide are based on actual working test cases. You can find complete, debugged examples in the SMock test suite:

  • Enterprise Scenarios - src/StaticMock.Tests/Tests/Examples/RealWorldExamples/EnterpriseScenarios.cs

These examples demonstrate:

  • Financial trading system - Risk calculation with market data mocking and compliance validation
  • Legacy code modernization - File processing with complex dependency chains
  • Web API order processing - Complete e-commerce flow with payment, inventory, and shipping
  • Document management - File system operations with virus scanning and metadata extraction
  • Multi-tenant data access - Database isolation and security testing

Running Real-World Examples

# Navigate to the src directory
cd src

# Run the real-world examples specifically
dotnet test --filter "ClassName=EnterpriseScenarios"

# Or run all example tests
dotnet test --filter "FullyQualifiedName~Examples"