Допустим, у меня есть простой класс с несколькими функциями:
public class MyClass
{
public int GetTotal(int myValue, string myString)
{
if (myValue > 10)
return GetTotal(myValue);
else
return GetTotal(myString);
}
public int GetTotal(int myValue)
{
return myValue * 25 / 12 + 156;
}
public int GetTotal(string myString)
{
return myString.Length * 25 / 48 + 27;
}
}
Я хотел бы провести модульное тестирование моей первой функции и "издеваться" над другими, int GetTotal (int myValue)
и int GetTotal (string myString)
, чтобы проверить только код внутри основной функции. Я использую Moq в качестве насмешливого фреймворка. Существуют ли какие-то уловки, которые позволили бы мне получить код функции, которую я хочу протестировать, и имитировать внутренний вызов других функций? Или мне нужно вызвать второй объект, подобный этому издеваться над всем?
public class MyCalculator
{
public int GetTotal(int myValue)
{
return myValue * 25 / 12 + 156;
}
public int GetTotal(string myString)
{
return myString.Length * 25 / 48 + 27;
}
}
public class MyClass
{
MyCalculator _Calculator;
public MyClass(MyCalculator calculator) { _Calculator = calculator; }
public int GetTotal(int myValue, string myString)
{
if (myValue > 10)
return _Calculator.GetTotal(myValue);
else
return _Calculator.GetTotal(myString);
}
}
Я знаю, что последний способ - самый чистый, но у меня есть много функций, вызывающих себя одна за другой, так что пришлось бы писать много классов.
Обновление
Макетная реализация Ответ Томаса:
public class MyClass
{
public int GetTotal(int myValue, string myString)
{
if (myValue > 10)
return GetTotal(myValue);
else
return GetTotal(myString);
}
public virtual int GetTotal(int myValue)
{
return myValue * 25 / 12 + 156;
}
public virtual int GetTotal(string myString)
{
return myString.Length * 25 / 48 + 27;
}
}
[TestClass]
public class Test
{
[TestMethod]
public void MyClass_GetTotal()
{
Mock myMockedClass = new Mock() {CallBase = true};
myMockedClass.Setup(x => x.GetTotal(It.IsAny())).Returns(1);
myMockedClass.Setup(x => x.GetTotal(It.IsAny())).Returns(2);
var actual = myMockedClass.Object.GetTotal(0,string.Empty);
Assert.AreEqual(2,actual);
}
}
Обновление 2
См. Также ответ Гишу для более глобального взгляда на эту «проблему».