Je discutais récemment avec des amis de la meilleure des deux méthodes suivantes pour renvoyer les résultats ou les appels de méthodes dans la même classe à partir de méthodes dans la même classe.
Ceci est un exemple très simplifié. En réalité, les fonctions sont beaucoup plus complexes.
Exemple:
public class MyClass
{
public bool FunctionA()
{
return FunctionB() % 2 == 0;
}
protected int FunctionB()
{
return new Random().Next();
}
}
Donc, pour tester cela, nous avons 2 méthodes.
Méthode 1: utilisez des fonctions et des actions pour remplacer la fonctionnalité des méthodes. Exemple:
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éthode 2: Rendre les membres virtuels, dériver une classe et dans une classe dérivée, utiliser Fonctions et actions pour remplacer des fonctionnalités Exemple:
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);
}
}
Je veux savoir qui est meilleur et aussi POURQUOI?
Mise à jour: NOTE: FunctionB peut aussi être public
FunctionB
est cassé par la conception. new Random().Next()
est presque toujours faux. Vous devriez injecter l'instance de Random
. ( Random
c'est aussi une classe mal conçue, ce qui peut causer quelques problèmes supplémentaires)
FunctionA
retourne un bool mais ne définit qu'une variable localex
et ne retourne rien.