Модульный тест, когда класс зависит от защищенного свойства базового класса - PullRequest
1 голос
/ 22 декабря 2011
public class MyBaseClass
{
    protected void OnSomeEvent(EventContext context)
    {
         SomeType  = _someService.DoSomeLogic(context);
    }

    public SomeType SomeType { get; private set; } 
}

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

public class MyClass : MyBaseClass
{
    public string Foo()
    {
        if (SomeType.SomeLogic())
            throw new InvalidOpertaionException();

        return "huzzah";
    }
}

Поток в других классах зависит от инициализации SomeType.

Как мне выполнить юнит-тест MyClass.Foo()?

[TestMethod]
public void Foo_ReturnsHuzzah()
{
    var result = new MyClass().Foo(); 
    Assert.IsHuzzah(result);   
}

Ответы [ 3 ]

3 голосов
/ 22 декабря 2011

_someService выглядит как внешняя зависимость. Я бы использовал Dependency Injection, чтобы сделать эту внешнюю зависимость инъекционной, а затем использовал бы фальшивую среду, чтобы внедрить что-то, что возвращает состояние, которое сделает остальные ваши тесты успешными.

Затем запустите публичный метод, который в конечном итоге вызывает OnSomeEvent, и вы можете протестировать всю цепочку обработки

2 голосов
/ 22 декабря 2011

Этот тип временной связи (событие должно быть инициировано до того, как вызов Foo действителен) часто считается недостатком проекта, поэтому первое, что я хотел бы сделать, - это вернуться к дизайну, чтобы убедиться в том, что у меня правильно.

Если вы не хотите идти по этому пути, самое простое решение - инициализировать SomeType с реализацией Null Object SomeType, например, так ...

class NullSomeType : SomeType
{
    public override bool SomeLogic() { return false; }
}

Тогда вы по умолчанию SomeType с нулевым объектом в конструкторе.

public MyBaseClass()
{
   SomeType = new NullSomeType();
}
0 голосов
/ 22 декабря 2011

Установите SomeType перед вызовом Foo()

...