Недавно я обсуждал с некоторыми друзьями, какой из следующих двух методов лучше всего заглушить, чтобы вернуть результаты или вызовы методов внутри одного класса из методов внутри того же класса.
Это очень упрощенный пример. На самом деле функции намного сложнее.
Пример:
public class MyClass
{
public bool FunctionA()
{
return FunctionB() % 2 == 0;
}
protected int FunctionB()
{
return new Random().Next();
}
}
Таким образом, чтобы проверить это у нас есть 2 метода.
Метод 1: Используйте функции и действия, чтобы заменить функциональность методов. Пример:
public class MyClass
{
public Func<int> FunctionB { get; set; }
public MyClass()
{
FunctionB = FunctionBImpl;
}
public bool FunctionA()
{
return FunctionB() % 2 == 0;
}
protected int FunctionBImpl()
{
return new Random().Next();
}
}
[TestClass]
public class MyClassTests
{
private MyClass _subject;
[TestInitialize]
public void Initialize()
{
_subject = new MyClass();
}
[TestMethod]
public void FunctionA_WhenNumberIsOdd_ReturnsTrue()
{
_subject.FunctionB = () => 1;
var result = _subject.FunctionA();
Assert.IsFalse(result);
}
}
Метод 2: Сделайте члены виртуальными, производным классом и в производном классе используйте Функции и Действия для замены функциональности. Пример:
public class MyClass
{
public bool FunctionA()
{
return FunctionB() % 2 == 0;
}
protected virtual int FunctionB()
{
return new Random().Next();
}
}
public class TestableMyClass
{
public Func<int> FunctionBFunc { get; set; }
public MyClass()
{
FunctionBFunc = base.FunctionB;
}
protected override int FunctionB()
{
return FunctionBFunc();
}
}
[TestClass]
public class MyClassTests
{
private TestableMyClass _subject;
[TestInitialize]
public void Initialize()
{
_subject = new TestableMyClass();
}
[TestMethod]
public void FunctionA_WhenNumberIsOdd_ReturnsTrue()
{
_subject.FunctionBFunc = () => 1;
var result = _subject.FunctionA();
Assert.IsFalse(result);
}
}
Я хочу знать, что лучше, а также почему?
Обновление: ПРИМЕЧАНИЕ: функция B также может быть общедоступной
FunctionB
сломан по дизайну. new Random().Next()
почти всегда неправильно. Вы должны ввести экземпляр Random
. ( Random
также плохо спроектированный класс, который может вызвать несколько дополнительных проблем)
FunctionA
возвращает bool, но устанавливает только локальную переменнуюx
и ничего не возвращает.