Moling a type, keeping the original behaviour of a specific method
I'm using Mi开发者_如何转开发crosoft Moles and am curious on the following topic:
- Is there any way to set the behaviour of a type (eg. to unimplemented) but keep the original behaviour of a single specific method?
My intention is to completely isolate the method to test (without knowing the methods that are called from the method to test) from its class.
The following code doesn't work for me as moles is disabled completely and any used submethod uses its original behaviour:MBaseObjectType.BehaveAsNotImplemented();
MolesContext.ExecuteWithoutMoles(() => mBaseObject.MethodToTest())
I guess you can only use a stub to achieve this behavior.
Here is a code sample. We will call MethodToTest
, all the other methods of ClassUnderTest
will throw an exception of type BehaviorNotImplementedException
.
public class ClassUnderTest
{
public virtual void MethodToTest()
{
Debug.WriteLine("In MethodToTest");
AnotherMethod();
}
public virtual void AnotherMethod()
{
Debug.WriteLine("In AnotherMethod");
}
}
Moles generates a stub class for us called SClassUnderTest
which we will use to call MethodToTest
.
public void Test1()
{
// A hack to call an overridden method.
var mi = typeof(ClassUnderTest).GetMethod("MethodToTest");
DynamicMethod dm = new DynamicMethod(
"BaseMethodToTest",
null,
new Type[] { typeof(SClassUnderTest) },
typeof(SClassUnderTest));
ILGenerator gen = dm.GetILGenerator();
gen.Emit(OpCodes.Ldarg_1);
gen.Emit(OpCodes.Call, mi);
gen.Emit(OpCodes.Ret);
var baseMethodCall = (Action<SClassUnderTest>)dm.CreateDelegate(
typeof(Action<SClassUnderTest>));
// Arrange the stub.
SClassUnderTest stub = new SClassUnderTest();
stub.InstanceBehavior = BehavedBehaviors.NotImplemented;
stub.MethodToTest01 = () =>
{
baseMethodCall(stub);
};
// Act.
stub.MethodToTest();
}
The original behavior may be preserved for all or specific Mole instances. The Fallthrough behavior disables Moles for unregistered methods.
// All instances:
MFileWatcher.Behavior = MoleBehaviors.Fallthrough;
// Specific instance
var original = new BaseObjectType(null);
var moledInstance = new MBaseObjectType(original) { InstanceBehavior = MoleBehaviors.Fallthrough };
Reference: http://social.msdn.microsoft.com/Forums/en-US/pex/thread/39af5a02-1cc9-4cf3-a254-3bdc923175db
精彩评论