Изменение типа, сохранение исходного поведения определенного метода

#c# #.net #unit-testing #moles #pex-and-moles

#c# #.net #модульное тестирование #родинки #pex-and-moles

Вопрос:

Я использую Microsoft Moles, и мне любопытно по следующей теме:

  • Есть ли какой-либо способ задать поведение типа (например. к неосуществленному) но сохранить исходное поведение одного конкретного метода?

Мое намерение состоит в том, чтобы полностью изолировать тестируемый метод (не зная методов, которые вызываются из тестируемого метода) от его класса.

Следующий код у меня не работает, поскольку moles полностью отключен, и любой используемый подметод использует свое исходное поведение:

 MBaseObjectType.BehaveAsNotImplemented();
MolesContext.ExecuteWithoutMoles(() => mBaseObject.MethodToTest())
  

Ответ №1:

Я думаю, вы можете использовать только заглушку для достижения такого поведения.

Вот пример кода. Мы будем вызывать MethodToTest , все другие методы ClassUnderTest будут выдавать исключение типа BehaviorNotImplementedException .

 public class ClassUnderTest
{
    public virtual void MethodToTest()
    {
        Debug.WriteLine("In MethodToTest");
        AnotherMethod();
    }
    public virtual void AnotherMethod()
    {
        Debug.WriteLine("In AnotherMethod");
    }
}
  

Moles генерирует для нас класс-заглушку с именем, SClassUnderTest который мы будем использовать для вызова 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();
}
  

Ответ №2:

Исходное поведение может быть сохранено для всех или определенных экземпляров Mole. Переходное поведение отключает родинки для незарегистрированных методов.

 // All instances:
MFileWatcher.Behavior = MoleBehaviors.Fallthrough;

// Specific instance
var original = new BaseObjectType(null);
var moledInstance = new MBaseObjectType(original) { InstanceBehavior = MoleBehaviors.Fallthrough };
  

Ссылка: http://social.msdn.microsoft.com/Forums/en-US/pex/thread/39af5a02-1cc9-4cf3-a254-3bdc923175db