Inspector 0.3.18
dotnet add package Inspector --version 0.3.18
NuGet\Install-Package Inspector -Version 0.3.18
<PackageReference Include="Inspector" Version="0.3.18" />
<PackageVersion Include="Inspector" Version="0.3.18" />
<PackageReference Include="Inspector" />
paket add Inspector --version 0.3.18
#r "nuget: Inspector, 0.3.18"
#:package Inspector@0.3.18
#addin nuget:?package=Inspector&version=0.3.18
#tool nuget:?package=Inspector&version=0.3.18
Inspector is a simple .NET Reflection API for white-box unit testing.
Why use white-box testing? Because building fully-tested .NET code shouldn't require breaking of encapsulation and unnecessary exposure of internal types as public, wrapping of well-defined external dependencies or resorting to integration testing.
install
Add the inspector package to your .NET project.
dotnet add package inspector
import
Import the Inspector namespace in your .NET source file. Most of the Inspector APIs are extension methods of the .NET Object and Type.
using Inspector;
use
Suppose you have the following class that serves as a base for a number of derived types in your system.
public class MyClass
{
protected readonly int field;
protected MyClass(int parameter) {
if (parameter < 42)
throw new ArgumentOutOfRangeException(nameof(parameter));
field = parameter;
}
}
Because the class members are meant to be used only by the derived types, its members have protected visibility and aren't directly accessible from unit tests. Testing this class can be done through its derived classes at the cost of duplicating the tests of the base class for each derived type. Alternatively, you could make members of this class internal and use the [assembly:InternalsVisibleTo()] attribute to allow your unit tests access them directly at the cost of breaking the encapsulation and making the class more accessible than intended. Finally, you could derive a special class that provides public API for accessing the protected members of its base in your unit tests. While this last option may be trivial, it is also wasteful and verbose.
With Inspector, you can create a new instance of a class with non-public constructor without redundant typecasting.
class MyClass
{
private string s;
private MyClass(int i) => s = i.ToString();
}
MyClass sut = Type<MyClass>.New(42);
You can use Inspector's strongly-typed extension methods to access non-public members.
string fieldValue = sut.Field<string>();
Assert.Equal("42", fieldValue);
You can verify that exceptions thrown by your class implement the expected contract.
var thrown = Assert.Throws<ArgumentOutOfRangeException>(() => Type<MyClass>.New(41));
Assert.Equal(sut.Constructor().Parameter().Name, thrown.ParamName);
Now suppose that MyClass is an external dependency in your code. Pretend that instead of a simple int parameter, its constructor requires a second-level dependency with complex setup that would not only be difficult to implement, it would also break the Law of Demeter and make your unit tests fragile. To deal with this problem, the conventional wisdom requires introduction of a new, testable abstraction in your code to encapsulate the external dependency and allow testing your code by mocking or stubbing your own abstraction instead of the dependency. While this option is straightforward, it could also be wasteful if the external dependency has a well-defined and stable API.
With Inspector, you can create an instance of this class without invoking its constructor and then manipulate its non-public members to prepare conditions expected by your code.
MyClass dependency = Type<MyClass>.Uninitialized();
dependency.Field<string>().Set("41");
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories (1)
Showing the top 1 popular GitHub repositories that depend on Inspector:
| Repository | Stars |
|---|---|
|
microsoft/service-fabric-dotnet
Service Fabric .NET Libraries
|
| Version | Downloads | Last Updated |
|---|---|---|
| 0.3.18 | 70 | 6/14/2026 |
| 0.3.17 | 139 | 5/30/2026 |
| 0.3.16 | 56 | 5/30/2026 |
| 0.3.15 | 59 | 5/30/2026 |
| 0.3.14 | 52 | 5/30/2026 |
| 0.3.13 | 56 | 5/30/2026 |
| 0.3.12 | 1,151 | 3/29/2026 |
| 0.3.11 | 99 | 3/29/2026 |
| 0.3.10 | 97 | 3/28/2026 |
| 0.3.9 | 156 | 3/28/2026 |
| 0.3.8 | 154 | 3/28/2026 |
| 0.3.7 | 158 | 3/28/2026 |
| 0.3.6 | 162 | 3/25/2026 |
| 0.3.5 | 96 | 3/24/2026 |
| 0.3.4 | 95 | 3/21/2026 |
| 0.3.3 | 91 | 3/21/2026 |
| 0.3.2 | 104 | 3/21/2026 |
| 0.3.1 | 96 | 3/21/2026 |
| 0.3.1-g3aca8719cf | 57 | 3/21/2026 |
| 0.2.21 | 94 | 3/21/2026 |