Как протестировать виртуальные методы с помощью кротов? - PullRequest
1 голос
/ 29 ноября 2011

Как я могу проверить функцию IsHappy, используя родинки?

class SomeClass
{
     protected virtual bool IsHappy(string mood)
     {
          return (mood == "Happy");
     }
}

Я пытался проверить, используя ли заглушку:

SSomeClass stub = new SSomeClass();
stub.CallBase = true;
Assert.IsTrue(stub.IsHappyString("Happy"));

... но метод IsHappyString возвращает ноль, в результате чего возникает исключение NullReference.

Итак, как я могу проверить реализацию по умолчанию метода IsHappy?

Ответы [ 2 ]

2 голосов
/ 29 ноября 2011

Я бы забыл о заглушках здесь. Заглушки / макеты предназначены для того, когда вы хотите имитировать поведение зависимости. Вы бы заглушили свой SomeClass, если бы имели SomeClassClient, который вы хотите протестировать, и он использовал SomeClass:

    public class Foo
    {
        public virtual int GetFoosInt()
        {
            return 12;
        }
    }
    public class FooClient
    {
        private Foo _foo;

        public FooClient(Foo foo)
        {
            _foo = foo;
        }

        public int AddOneToFoosInt()
        {
            return _foo.GetFoosInt() + 1;
        }
    }

В этом примере при тестировании FooClient вы хотите проверить, чтобы он возвращал на единицу больше, чем «GetFoosInt ()». На самом деле вам все равно, что такое FoosInt для тестирования FooClient. Итак, вы создаете заглушку Foo, в которой вы можете настроить GetFoosInt, чтобы он возвращал все, что вы хотите.

В вашем случае, тестируя защищенного виртуального участника, я бы сказал:

[TestClass]
public class SomeClassTest
{
    private class DummySomeClass : SomeClass
    {
        public bool IsHappyWrapper(string mood)
        {
            return IsHappy(mood);
        }
    }

    [TestMethod]
    public void SomeTest()
    {
        var myClass = new DummySomeClass();

        Assert.IsTrue(myClass.IsHappyWrapper("Happy"));
    }
}

Это дает вам «прямой» доступ к защищенной виртуальной машине для проверки поведения по умолчанию. Единственное предостережение: если вы начнете определять абстрактные элементы и добавлять их в SomeClass в целом, вам придется добавить их и к этому фиктивному наследнику, добавляя к издержкам на обслуживание тестирования.

Пурист во мне говорит, что вы должны оставлять защищенных членов в покое и проверять их только через общедоступный интерфейс. Но это может или не может быть практичным в вашей ситуации, и я не вижу никакого вреда в этом подходе.

1 голос
/ 29 ноября 2011

Заглушки и родинки предназначены для изоляции класса от любых зависимостей, которые у него есть, либо от окружения, либо от классов.Этот класс не имеет никаких зависимостей, так почему же вы пытаетесь вызвать или заглушить его?

Если вы хотите убедиться, что этот базовый класс работает должным образом, когда люди переопределяют его, вам нужно будет создать тестовую реализацию.,В этом случае это примерно так должно выглядеть в ваших тестовых примерах:

public SomeClassTestAdapter : SomeClass
{
    public bool GetIsHappy(string mood)
    {
        return IsHappy(mood);
    }
}

[Test]
public void ShouldReturnTrueWhenPassedHappy()
{
    var classUnderTest = new SomeClassTestAdapter();
    bool result = classUnderTest.IsHappy("Happy");
    Assert.IsTrue(result, "Expected result to be true");
}

[Test]
public void ShouldReturnFalseWhenPassedLowerCaseHappy()
{
    var classUnderTest = new SomeClassTestAdapter();
    bool result = classUnderTest.IsHappy("happy");
    Assert.IsFalse(result, "Expected result to be false");
}

[Test]
public void ShouldReturnFalseWhenPassedNull()
{
    var classUnderTest = new SomeClassTestAdapter();
    bool result = classUnderTest.IsHappy(null);
    Assert.IsFalse(result, "Expected result to be false");
}

И т. Д.

В этом коде нет места, в котором должны быть сжаты заглушки или родинки.1008 *

Если вы не хотите создавать класс адаптера для этого случая, вы можете использовать встроенные функции .Net, а не большую платную зависимость, такую ​​как Moles.Размышления и динамика позволяют получить доступ к защищенным или закрытым членам.Смотрите этот пример:

...