In general, I design classes in such a manner as to not require access to privates for testing purposes. An InternalsVisibleTo
can also assist.
However, I'm currently dealing with a codebase that has a few area which have become reliant on the private accessors mechanism in VSTS (i.e., using VSCodeGenAccessors
to generate *_Accessor
classes which have forwarding that use reflection to invoke private
members (and optionally internal
ones too) on a class.
So I've got code like:
ClassUnderTest target = new ClassUnderTest();
var accessor = ClassUnderTest_Accessor.AttachShadow( target );
accessor.PrivateMethod();
Assert.True( accessor._privateMethodWasCalled);
accessor.PrivateProperty = 5;
Assert.Equal( accessor.PrivateProperty, 5);
(Yes, riddled with antipatterns - but please dont shoot the messenger)
I have a number of problems with this:
- I'd like to be able to clarify which I privates I need
- I'd prefer not to be invoking dialogs (Yes, I'm a CRaholic)
- I'd prefer not to involve code generation in the picture
So I'd like to be able to transform the above code to something like:
var target = new ClassUnderTest();
IClassUnderTestInterface accessor = Shadow.Create<IClassUnderTestInterface>( target );
accessor.PrivateMethod();
Assert.True( accessor._privateMethodWasCalled);
accessor.PrivateProperty = 5;
Assert.Equal( accessor.PrivateProperty, 5);
With only the following interface sitting in my test assembly, and no generated code or custom build steps :-
interface IClassUnderTestInterface
{
int PrivateProperty {get; set;}
bool _privateMethodWasCalled {get; }
void PrivateMethod();
}
From there, I'd be able to use CodeRush or Ctrl K M to generate new shadow methods onto the interface with only a keystroke.
The missing bit would be having a method I Shadow.Create<I>( Object o)
which would
1. generate a dynamic proxy that implements the interface
1. verify that the object o
to be wrapped has all the members dictated by the interface
1. bnous: manage the forwarding of properties representing fields (i.e., the `_privateMethodWasCalled' case) correctly
So, does anyone know a library that implements something like this (or feel bored enough to write it?)
One obvious drawback is that youo dont know if the interface isnt commpatible with the ClassUnderTest until runtime, but that's OK as this would only be for tests. Also AIUI, the private accessors mechanism also requires the triggering of a recompile to sync stuff up from time to time.
Or is there a way better approach I'm missing? (Remembering I dont want to go blanket ugrading al privates to internal or public and dont want to have to rewrite working code)
Using xUnit.net, .NET 3.5; Open to using any dynamic proxy library or other