Recientemente estuve discutiendo con algunos amigos cuál de los siguientes 2 métodos es el mejor para resguardar los resultados devueltos o las llamadas a métodos dentro de la misma clase de los métodos dentro de la misma clase.
Este es un ejemplo muy simplificado. En realidad, las funciones son mucho más complejas.
Ejemplo:
public class MyClass
{
public bool FunctionA()
{
return FunctionB() % 2 == 0;
}
protected int FunctionB()
{
return new Random().Next();
}
}
Entonces, para probar esto, tenemos 2 métodos.
Método 1: utilice funciones y acciones para reemplazar la funcionalidad de los métodos. Ejemplo:
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);
}
}
Método 2: Haga que los miembros sean virtuales, la clase derivada y en la clase derivada use Funciones y Acciones para reemplazar la funcionalidad Ejemplo:
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);
}
}
Quiero saber cuál es mejor y también ¿POR QUÉ?
Actualización: NOTA: La función B también puede ser pública
FunctionBestá roto por diseño. new Random().Next()Casi siempre está mal. Debe inyectar la instancia de Random. ( Randomtambién es una clase mal diseñada, que puede causar algunos problemas adicionales)
FunctionAdevuelve un bool pero solo establece una variable localxy no devuelve nada.