Ich habe kürzlich mit einigen Freunden diskutiert, welche der folgenden 2 Methoden am besten geeignet ist, um Ergebnisse oder Aufrufe von Methoden innerhalb derselben Klasse von Methoden innerhalb derselben Klasse zurückzugeben.
Dies ist ein sehr vereinfachtes Beispiel. In Wirklichkeit sind die Funktionen viel komplexer.
Beispiel:
public class MyClass
{
public bool FunctionA()
{
return FunctionB() % 2 == 0;
}
protected int FunctionB()
{
return new Random().Next();
}
}
Um dies zu testen, haben wir 2 Methoden.
Methode 1: Verwenden Sie Funktionen und Aktionen, um die Funktionalität der Methoden zu ersetzen. Beispiel:
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);
}
}
Methode 2: machen Sie Mitglieder virtuell, leiten Sie Klasse ab, und verwenden Sie in abgeleiteter Klasse Funktionen und Aktionen, um Funktionalität zu ersetzen Beispiel:
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);
}
}
Ich möchte wissen, was besser ist und auch WARUM?
Update: HINWEIS: FunctionB kann auch öffentlich sein
public static
nur in einer anderen Klasse befinden.
FunctionB
ist defekt durch Design. new Random().Next()
ist fast immer falsch. Sie sollten die Instanz von injizieren Random
. ( Random
ist auch eine schlecht gestaltete Klasse, die ein paar zusätzliche Probleme verursachen kann)
FunctionA
Gibt einen Bool zurück, setzt aber nur eine lokale Variablex
und gibt nichts zurück.