Assembly: MbUnit (in MbUnit.dll) Version: 3.2.0.0 (3.2.528.0)
Syntax
| C# |
|---|
public sealed class Mirror |
| Visual Basic (Declaration) |
|---|
Public NotInheritable Class Mirror |
Remarks
Writing tests that require access to non-public members is not recommended. Non-public members should be considered internal implementation details of the subject under test. Relying on their behavior can yield brittle tests.
These reflection helpers are not intended to assist with all possible reflection scenarios. For everything else, use the standard .Net reflection library.
Another useful function related to Mirror is CoerceDelegate(Type, Delegate) which you can use to convert a delegate from one type to another. This is useful for creating instances of non-public delegate types. In particular, the AddHandler(Delegate) method automatically coerces delegates if needed.
Examples
In this example, we use a Mirror to access non-public members of an object and static members of an internal class.
// A sample object with various members including a private nested class // that has a public yet inaccessible static method. public class SampleObject { private int privateField; private int PrivateProperty { get; set;} private event EventHandler PrivateEvent; private int PrivateMethod(int a, int b) { ... } private static class PrivateNestedClass { public int StaticMethod(object y) { ... } public int OverloadedMethod(object y) { ... } public int OverloadedMethod(string y) { ... } public T GenericMethod<T>(T x) { ... } } } internal class InternalObject { ... } internal delegate int InternalDelegate(InternalObject x); // A sample test fixture. public class Fixture { [Test] public void Test() { // Setup. SampleObject obj = new SampleObject(); Mirror objMirror = Mirror.ForObject(obj); // Reading from a private field. int privateFieldValue = (int) objMirror["privateField"].Value; // Writing to a private property. objMirror["PrivateProperty"].Value = 42; // Obtaining a mirror for a value at index 5 in a private indexed property. Mirror valueMirror = objMirror["Item"][5].ValueAsMirror; // Invoking a private method. int result = (int) objMirror["PrivateMethod"].Invoke(1, 2); // Accessing a private type. Type privateNestedClass = objMirror["PrivateNestedClass"].Type; Mirror privateNestedClassMirror = Mirror.ForType(privateNestedClass); // Invoking a static method. int result2 = privateNestedClassMirror["StaticMethod"].Invoke(42); // Invoking an overloaded static method when we cannot determine the parameter // type automatically from the arguments, such as when an argument is null. int result2 = privateNestedClassMirror["OverloadedMethod"].WithSignature(typeof(object)).Invoke(null); int result3 = privateNestedClassMirror["OverloadedMethod"].WithSignature(typeof(string)).Invoke(null); // Invoking a generic method. int result3 = privateNestedClassMirror["GenericMethod"].Invoke(42); // Invoking a generic method using specific type arguments. object result4 = privateNestedClassMirror["GenericMethod"].WithTypeArgs(typeof(object)).Invoke(42); // Creating an instance of an internal object. Mirror internalObjTypeMirror = Mirror.ForType("My.Namespace.InternalObject", "MyAssembly"); object internalObj = internalObjTypeMirror.CreateInstance(); // Creating an instance of an internal delegate. // Notice that the Mirror automatically adapts the provided delegate signature // to the actual delegate signature to make it easier to write tests when the delegate // parameter or result types are themselves inaccessible. Mirror internalDelegateTypeMirror = Mirror.ForType("My.Namespace.InternalDelegate", "MyAssembly"); Delegate internalDelegate = internalDelegateTypeMirror.CreateDelegate( new Func<object, int>(x => { return 5; })); } }
