Niedawno dyskutowałem z przyjaciółmi, która z poniższych 2 metod najlepiej jest usunąć wyniki lub wywołania metod z tej samej klasy z metod z tej samej klasy.
To bardzo uproszczony przykład. W rzeczywistości funkcje są znacznie bardziej złożone.
Przykład:
public class MyClass
{
public bool FunctionA()
{
return FunctionB() % 2 == 0;
}
protected int FunctionB()
{
return new Random().Next();
}
}
Aby to przetestować, mamy 2 metody.
Metoda 1: Użyj funkcji i akcji, aby zastąpić funkcjonalność metod. Przykład:
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);
}
}
Metoda 2: Uczyń członków wirtualnymi, wyprowadź klasę i skorzystaj z klasy pochodnej Funkcje i akcje zastępujące funkcjonalność Przykład:
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);
}
}
Chcę wiedzieć, który jest lepszy, a także DLACZEGO?
Aktualizacja: UWAGA: Funkcja B może być również publiczna
FunctionB
jest zepsuty przez projekt. new Random().Next()
prawie zawsze się myli. Powinieneś wstrzyknąć instancję Random
. ( Random
jest także źle zaprojektowaną klasą, która może powodować kilka dodatkowych problemów)
FunctionA
zwraca bool, ale ustawia tylko zmienną lokalnąx
i niczego nie zwraca.