{"id":37057049,"url":"https://github.com/svetlova/static-mock","last_synced_at":"2026-01-14T06:27:18.618Z","repository":{"id":45330173,"uuid":"357657542","full_name":"SvetlovA/static-mock","owner":"SvetlovA","description":"SMock is opensource lib for mocking static and instance methods and properties.","archived":false,"fork":false,"pushed_at":"2026-01-13T14:36:24.000Z","size":15917,"stargazers_count":14,"open_issues_count":0,"forks_count":3,"subscribers_count":2,"default_branch":"master","last_synced_at":"2026-01-13T16:33:31.055Z","etag":null,"topics":["mock","mocking","moq","static","test","testing","tests","unittesting","unittests"],"latest_commit_sha":null,"homepage":"https://svetlova.github.io/static-mock/","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/SvetlovA.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":["SvetlovA"],"patreon":"svtlv","open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"lfx_crowdfunding":null,"custom":["https://boosty.to/svtlv"]}},"created_at":"2021-04-13T18:50:18.000Z","updated_at":"2026-01-13T14:36:56.000Z","dependencies_parsed_at":"2023-11-30T17:35:55.513Z","dependency_job_id":"ccb5c7bd-1da3-40b8-8e59-c9ae5a6f4a5b","html_url":"https://github.com/SvetlovA/static-mock","commit_stats":null,"previous_names":[],"tags_count":18,"template":false,"template_full_name":null,"purl":"pkg:github/SvetlovA/static-mock","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SvetlovA%2Fstatic-mock","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SvetlovA%2Fstatic-mock/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SvetlovA%2Fstatic-mock/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SvetlovA%2Fstatic-mock/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/SvetlovA","download_url":"https://codeload.github.com/SvetlovA/static-mock/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SvetlovA%2Fstatic-mock/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28412211,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T05:26:33.345Z","status":"ssl_error","status_checked_at":"2026-01-14T05:21:57.251Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["mock","mocking","moq","static","test","testing","tests","unittesting","unittests"],"created_at":"2026-01-14T06:27:17.985Z","updated_at":"2026-01-14T06:27:18.606Z","avatar_url":"https://github.com/SvetlovA.png","language":"C#","funding_links":["https://github.com/sponsors/SvetlovA","https://patreon.com/svtlv","https://boosty.to/svtlv"],"categories":[],"sub_categories":[],"readme":"# 🎯 SMock - Static \u0026 Instance Method Mocking for .NET\n\n\u003cdiv align=\"center\"\u003e\n\n[![NuGet Version](https://img.shields.io/nuget/v/SMock.svg?style=for-the-badge\u0026logo=nuget)](https://www.nuget.org/packages/SMock)\n[![NuGet Downloads](https://img.shields.io/nuget/dt/SMock.svg?style=for-the-badge\u0026logo=nuget)](https://www.nuget.org/packages/SMock)\n[![GitHub Stars](https://img.shields.io/github/stars/SvetlovA/static-mock?style=for-the-badge\u0026logo=github)](https://github.com/SvetlovA/static-mock/stargazers)\n[![License](https://img.shields.io/badge/license-MIT-blue.svg?style=for-the-badge)](LICENSE)\n[![.NET Version](https://img.shields.io/badge/.NET-Standard%202.0%2B-purple.svg?style=for-the-badge)](https://dotnet.microsoft.com/)\n\n**A mocking library that makes testing static methods easier!**\n\n\u003c/div\u003e\n\n---\n\n## Why SMock?\n\nSMock breaks down the barriers of testing legacy code, third-party dependencies, and static APIs. Built on [MonoMod](https://github.com/MonoMod/MonoMod) runtime modification technology, SMock gives you the power to mock what others can't.\n\n- **Mock Static Methods**: The only .NET library that handles static methods seamlessly\n- **Two API Styles**: Choose Hierarchical (with validation) or Sequential (disposable) patterns\n- **Zero Configuration**: Works with your existing test frameworks (NUnit, xUnit, MSTest)\n- **Complete Feature Set**: Async/await, parameter matching, callbacks, exceptions, unsafe code\n\n---\n\n## Installation\n\n### Package Manager\n```powershell\nInstall-Package SMock\n```\n\n### .NET CLI\n```bash\ndotnet add package SMock\n```\n\n\u003e 💡 **Pro Tip**: SMock works great with any testing framework - NUnit, xUnit, MSTest, you name it!\n\n---\n\n## 🚀 Quick Start\n\n```csharp\n// Mock a static method in just one line - Sequential API\nusing var mock = Mock.Setup(() =\u003e File.ReadAllText(\"config.json\"))\n    .Returns(\"{ \\\"setting\\\": \\\"test\\\" }\");\n\n// Your code now uses the mocked value!\nvar content = File.ReadAllText(\"config.json\"); // Returns test JSON\n\n// Or use the Hierarchical API with inline validation\nMock.Setup(() =\u003e DateTime.Now, () =\u003e\n{\n    var result = DateTime.Now;\n    Assert.AreEqual(new DateTime(2024, 1, 1), result);\n}).Returns(new DateTime(2024, 1, 1));\n```\n\n---\n\n## Core Concepts\n\n### Hook-Based Runtime Modification\n\nSMock uses [MonoMod](https://github.com/MonoMod/MonoMod) to create **runtime hooks** that intercept method calls:\n\n- **Non-Invasive**: No source code changes required\n- **Isolated**: Each test runs in isolation\n- **Fast**: Minimal performance overhead\n- **Auto-Cleanup**: Hooks automatically removed after test completion\n\n### Mock Lifecycle\n\n```csharp\n// 1. Setup: Create a mock for the target method\nvar mock = Mock.Setup(() =\u003e DateTime.Now);\n\n// 2. Configure: Define return values or behaviors\nmock.Returns(new DateTime(2024, 1, 1));\n\n// 3. Execute: Run your code - calls are intercepted\nvar now = DateTime.Now; // Returns mocked value\n\n// 4. Cleanup: Dispose mock (Sequential) or automatic (Hierarchical)\nmock.Dispose(); // Or automatic with 'using'\n```\n\n---\n\n## API Styles\n\nSMock provides **two distinct API patterns** to fit different testing preferences:\n\n### Sequential API\n\nPerfect for **clean, scoped mocking** with automatic cleanup:\n\n```csharp\n[Test]\npublic void TestFileOperations()\n{\n    // Mock file existence check\n    using var existsMock = Mock.Setup(() =\u003e File.Exists(\"test.txt\"))\n        .Returns(true);\n\n    // Mock file content reading\n    using var readMock = Mock.Setup(() =\u003e File.ReadAllText(\"test.txt\"))\n        .Returns(\"Hello World\");\n\n    // Your code under test\n    var processor = new FileProcessor();\n    var result = processor.ProcessFile(\"test.txt\");\n\n    Assert.AreEqual(\"HELLO WORLD\", result);\n} // Mocks automatically cleaned up here\n```\n\n### Hierarchical API\n\nPerfect for **inline validation** during mock execution:\n\n```csharp\n[Test]\npublic void TestDatabaseConnection()\n{\n    var expectedConnectionString = \"Server=localhost;Database=test;\";\n\n    Mock.Setup(context =\u003e DatabaseConnection.Connect(It.IsAny\u003cstring\u003e()), () =\u003e\n    {\n        // This validation runs DURING the mock execution\n        var actualCall = DatabaseConnection.Connect(expectedConnectionString);\n        Assert.IsNotNull(actualCall);\n        Assert.IsTrue(actualCall.IsConnected);\n    }).Returns(new MockConnection { IsConnected = true });\n\n    // Test your service\n    var service = new DatabaseService();\n    service.InitializeConnection(expectedConnectionString);\n}\n```\n\n---\n\n## ⚡ Performance\n\nSMock is designed for **minimal performance impact**:\n\n- **Runtime Hooks**: Only active during tests\n- **Zero Production Overhead**: No dependencies in production builds\n- **Efficient Interception**: Built on MonoMod's optimized IL modification\n- **Benchmarked**: Comprehensive performance testing with BenchmarkDotNet\n\n### Performance Characteristics\n\n| Operation | Overhead | Notes |\n|-----------|----------|--------|\n| **Mock Setup** | ~1-2ms | One-time cost per mock |\n| **Method Interception** | \u003c0.1ms | Minimal runtime impact |\n| **Cleanup** | \u003c1ms | Automatic hook removal |\n| **Memory Usage** | Minimal | Temporary IL modifications only |\n\n---\n\n## ⚠️ Known Issues \u0026 Solutions\n\n### Compiler Optimization Issue\n\nIf your mocks are not being applied and you're getting the original method behavior instead of the mocked behavior, this is likely due to compiler optimizations. The compiler may inline or optimize method calls, preventing SMock from intercepting them.\n\n**Solutions**:\n\n1. **Run tests in Debug configuration**:\n   ```bash\n   dotnet test --configuration Debug\n   ```\n\n2. **Disable compiler optimization in your test project** by adding this to your `.csproj`:\n   ```xml\n   \u003cPropertyGroup\u003e\n     \u003cOptimize\u003efalse\u003c/Optimize\u003e\n   \u003c/PropertyGroup\u003e\n   ```\n\n3. **Disable optimization for specific methods** using the `MethodImpl` attribute:\n   ```csharp\n   [Test]\n   [MethodImpl(MethodImplOptions.NoOptimization)]\n   public void MyTestMethod()\n   {\n       using var mock = Mock.Setup(() =\u003e File.ReadAllText(\"config.json\"))\n           .Returns(\"{ \\\"setting\\\": \\\"test\\\" }\");\n\n       // Your test code here\n   }\n   ```\n\nThis issue typically occurs in Release builds where the compiler aggressively optimizes method calls. Using any of the above solutions will ensure your mocks work correctly.\n\n---\n\n## Additional Resources\n\n- **[API Documentation](https://svetlova.github.io/static-mock/api/index.html)**\n- **[More Examples](https://github.com/SvetlovA/static-mock/tree/master/src/StaticMock.Tests/Tests)**\n- **[Hierarchical API Examples](https://github.com/SvetlovA/static-mock/tree/master/src/StaticMock.Tests/Tests/Hierarchical)**\n- **[Sequential API Examples](https://github.com/SvetlovA/static-mock/tree/master/src/StaticMock.Tests/Tests/Sequential)**\n\n---\n\n## 📄 License\n\nThis library is available under the [MIT license](https://github.com/SvetlovA/static-mock/blob/master/LICENSE).\n\n---\n\n\u003cdiv align=\"center\"\u003e\n\n## 🚀 Ready to revolutionize your .NET testing?\n\n**[⚡ Get Started Now](#installation)** | **[📚 View Examples](https://github.com/SvetlovA/static-mock/tree/master/src/StaticMock.Tests/Tests)** | **[💬 Join Discussion](https://github.com/SvetlovA/static-mock/discussions)**\n\n---\n\n*Made with ❤️ by [@SvetlovA](https://github.com/SvetlovA) and the SMock community*\n\n\u003c/div\u003e","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsvetlova%2Fstatic-mock","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsvetlova%2Fstatic-mock","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsvetlova%2Fstatic-mock/lists"}