![]() |
VOOZH | about |
dotnet add package SMock --version 2.6.0
NuGet\Install-Package SMock -Version 2.6.0
<PackageReference Include="SMock" Version="2.6.0" />
<PackageVersion Include="SMock" Version="2.6.0" />Directory.Packages.props
<PackageReference Include="SMock" />Project file
paket add SMock --version 2.6.0
#r "nuget: SMock, 2.6.0"
#:package SMock@2.6.0
#addin nuget:?package=SMock&version=2.6.0Install as a Cake Addin
#tool nuget:?package=SMock&version=2.6.0Install as a Cake Tool
<div align="center">
👁 NuGet Version
👁 NuGet Downloads
👁 GitHub Stars
👁 .NET Version
A mocking library that makes testing static methods easier!
</div>
SMock breaks down the barriers of testing legacy code, third-party dependencies, and static APIs. Built on MonoMod runtime modification technology, SMock gives you the power to mock what others can't.
Install-Package SMock
dotnet add package SMock
💡 Pro Tip: SMock works great with any testing framework - NUnit, xUnit, MSTest, you name it!
// Mock a static method in just one line - Sequential API
using var mock = Mock.Setup(() => File.ReadAllText("config.json"))
.Returns("{ \"setting\": \"test\" }");
// Your code now uses the mocked value!
var content = File.ReadAllText("config.json"); // Returns test JSON
// Or use the Hierarchical API with inline validation
Mock.Setup(() => DateTime.Now, () =>
{
var result = DateTime.Now;
Assert.AreEqual(new DateTime(2024, 1, 1), result);
}).Returns(new DateTime(2024, 1, 1));
SMock uses MonoMod to create runtime hooks that intercept method calls:
// 1. Setup: Create a mock for the target method
var mock = Mock.Setup(() => DateTime.Now);
// 2. Configure: Define return values or behaviors
mock.Returns(new DateTime(2024, 1, 1));
// 3. Execute: Run your code - calls are intercepted
var now = DateTime.Now; // Returns mocked value
// 4. Cleanup: Dispose mock (Sequential) or automatic (Hierarchical)
mock.Dispose(); // Or automatic with 'using'
SMock provides two distinct API patterns to fit different testing preferences:
Perfect for clean, scoped mocking with automatic cleanup:
[Test]
public void TestFileOperations()
{
// Mock file existence check
using var existsMock = Mock.Setup(() => File.Exists("test.txt"))
.Returns(true);
// Mock file content reading
using var readMock = Mock.Setup(() => File.ReadAllText("test.txt"))
.Returns("Hello World");
// Your code under test
var processor = new FileProcessor();
var result = processor.ProcessFile("test.txt");
Assert.AreEqual("HELLO WORLD", result);
} // Mocks automatically cleaned up here
Perfect for inline validation during mock execution:
[Test]
public void TestDatabaseConnection()
{
var expectedConnectionString = "Server=localhost;Database=test;";
Mock.Setup(() => DatabaseConnection.Connect(It.IsAny<string>()), () =>
{
// This validation runs DURING the mock execution
var actualCall = DatabaseConnection.Connect(expectedConnectionString);
Assert.IsNotNull(actualCall);
Assert.IsTrue(actualCall.IsConnected);
}).Returns(new MockConnection { IsConnected = true });
// Test your service
var service = new DatabaseService();
service.InitializeConnection(expectedConnectionString);
}
SMock is designed for minimal performance impact:
| Operation | Overhead | Notes |
|---|---|---|
| Mock Setup | ~1-2ms | One-time cost per mock |
| Method Interception | <0.1ms | Minimal runtime impact |
| Cleanup | <1ms | Automatic hook removal |
| Memory Usage | Minimal | Temporary IL modifications only |
If 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.
Solutions:
Run tests in Debug configuration:
dotnet test --configuration Debug
Disable compiler optimization in your test project by adding this to your .csproj:
<PropertyGroup>
<Optimize>false</Optimize>
</PropertyGroup>
Disable optimization for specific methods using the MethodImpl attribute:
[Test]
[MethodImpl(MethodImplOptions.NoOptimization)]
public void MyTestMethod()
{
using var mock = Mock.Setup(() => File.ReadAllText("config.json"))
.Returns("{ \"setting\": \"test\" }");
// Your test code here
}
This 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.
This library is available under the MIT license.
<div align="center">
⚡ Get Started Now | 📚 View Examples | 💬 Join Discussion
Made with ❤️ by @SvetlovA and the SMock community
</div>
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 net5.0 was computed. net5.0-windows net5.0-windows was computed. net6.0 net6.0 was computed. net6.0-android net6.0-android was computed. net6.0-ios net6.0-ios was computed. net6.0-maccatalyst net6.0-maccatalyst was computed. net6.0-macos net6.0-macos was computed. net6.0-tvos net6.0-tvos was computed. net6.0-windows net6.0-windows was computed. net7.0 net7.0 was computed. net7.0-android net7.0-android was computed. net7.0-ios net7.0-ios was computed. net7.0-maccatalyst net7.0-maccatalyst was computed. net7.0-macos net7.0-macos was computed. net7.0-tvos net7.0-tvos was computed. net7.0-windows net7.0-windows was computed. net8.0 net8.0 was computed. net8.0-android net8.0-android was computed. net8.0-browser net8.0-browser was computed. net8.0-ios net8.0-ios was computed. net8.0-maccatalyst net8.0-maccatalyst was computed. net8.0-macos net8.0-macos was computed. net8.0-tvos net8.0-tvos was computed. net8.0-windows net8.0-windows was computed. net9.0 net9.0 was computed. net9.0-android net9.0-android was computed. net9.0-browser net9.0-browser was computed. net9.0-ios net9.0-ios was computed. net9.0-maccatalyst net9.0-maccatalyst was computed. net9.0-macos net9.0-macos was computed. net9.0-tvos net9.0-tvos was computed. net9.0-windows net9.0-windows was computed. net10.0 net10.0 was computed. net10.0-android net10.0-android was computed. net10.0-browser net10.0-browser was computed. net10.0-ios net10.0-ios was computed. net10.0-maccatalyst net10.0-maccatalyst was computed. net10.0-macos net10.0-macos was computed. net10.0-tvos net10.0-tvos was computed. net10.0-windows net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 netcoreapp2.0 was computed. netcoreapp2.1 netcoreapp2.1 was computed. netcoreapp2.2 netcoreapp2.2 was computed. netcoreapp3.0 netcoreapp3.0 was computed. netcoreapp3.1 netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 netstandard2.0 is compatible. netstandard2.1 netstandard2.1 was computed. |
| .NET Framework | net461 net461 was computed. net462 net462 is compatible. net463 net463 was computed. net47 net47 is compatible. net471 net471 is compatible. net472 net472 is compatible. net48 net48 is compatible. net481 net481 is compatible. |
| MonoAndroid | monoandroid monoandroid was computed. |
| MonoMac | monomac monomac was computed. |
| MonoTouch | monotouch monotouch was computed. |
| Tizen | tizen40 tizen40 was computed. tizen60 tizen60 was computed. |
| Xamarin.iOS | xamarinios xamarinios was computed. |
| Xamarin.Mac | xamarinmac xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos xamarinwatchos was computed. |
This package is not used by any NuGet packages.
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 2.6.0 | 2,381 | 11/27/2025 |
| 2.5.0 | 3,313 | 8/18/2025 |
| 2.4.0 | 2,394 | 3/21/2025 |
| 2.3.0 | 3,262 | 11/20/2024 |
| 2.2.0 | 24,387 | 2/8/2024 |
| 2.1.0 | 152,070 | 8/29/2023 |
| 2.0.0 | 377 | 7/16/2023 |
| 1.8.0 | 1,002 | 12/13/2022 |
| 1.7.1 | 2,178 | 8/27/2022 |
| 1.7.0 | 637 | 8/27/2022 |
| 1.6.0 | 790 | 12/21/2021 |
| 1.5.0 | 558 | 8/2/2021 |
| 1.4.0 | 551 | 7/18/2021 |
| 1.3.0 | 549 | 7/1/2021 |
| 1.2.1 | 551 | 5/17/2021 |
| 1.2.0 | 606 | 5/5/2021 |
| 1.1.0 | 544 | 4/30/2021 |
| 1.0.0 | 654 | 4/27/2021 |