2011-11-29 2 views
1

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

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

Я пытался проверить, если с помощью Stub:

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

... но IsHappyString метод возвращает значение NULL, таким образом, бросая NullReference исключение.

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

ответ

1

Stubs and Moles предназначены для изоляции класса от любых зависимостей, которые он имеет, либо от зависимостей окружающей среды, либо от зависимостей классов. У этого класса нет никаких зависимостей, так почему вы пытаетесь намотать или заглушить его?

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

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"); 
} 

Etc.

Там нет места в этом коде, окурки или родинки должны быть сжаты в

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

+0

Метод IsHappy является «защищенным». Я не могу получить к нему доступ, вызывая метод непосредственно из теста класса. – Ian

+0

@Ian: Извините, так долго требовалось, чтобы вернуться к этому. Обновлен мой ответ –

2

Я забыл бы о окурки здесь. Stubs/mocks предназначены, когда вы хотите подделать поведение зависимости. Вы бы окурок ваш 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 в целом, вам также придется добавить их к этому фиктивному наследнику, добавив к тестированию накладные расходы на техническое обслуживание.

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

+0

Есть ли возможности в Moles.NET, которые могут «автоматизировать» это? В Moles есть некоторые элементы управления поведением (Fallout и т. Д.).Могут ли они использоваться в качестве замены для ручного создания класса Dummy? – Ian

+0

Не знаю. Я использовал Moles в основном для издевательства внешних зависимостей, таких как сторонние статические методы, файлы, графический интерфейс и т. Д. Я не использовал его полностью как общий издевательский движок, предпочитая вместо этого использовать Moq. Молес довольно мощный, поэтому меня это не удивило бы, если бы это было возможно, но, к сожалению, я не знаю, как сверху. –

+0

Ранее MSTest был способен генерировать «Accessors» - специальные сборки, которые выставляют любой защищенный/закрытый член. К сожалению, похоже, что они отменили поддержку этой функции (хотя я не помню, где я ее читал). –

Смежные вопросы