开发者

Moling a type, keeping the original behaviour of a specific method

开发者 https://www.devze.com 2023-03-06 05:48 出处:网络
I\'m using Mi开发者_如何转开发crosoft Moles and am curious on the following topic: Is there any way to set the behaviour

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

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号