Unser System ist so strukturiert, dass wir viele wichtige Informationen für unsere Berechnungen und andere solche Logik aus Nachschlagetabellen erhalten. Beispiele wären alle Arten von unterschiedlichen Sätzen (wie Zinssätze oder Beitragssätze), Daten (wie Datum des Inkrafttretens) und alle Arten von verschiedenen sonstigen Informationen.
Warum haben sie beschlossen, alles so zu strukturieren? Weil sich einige dieser Informationen ziemlich oft ändern. Zum Beispiel ändern sich einige unserer Preise jährlich. Sie wollten versuchen, Codeänderungen zu minimieren. Die Hoffnung war nur, dass sich die Nachschlagetabellen ändern würden und der Code einfach funktionieren würde (keine Codeänderungen).
Leider denke ich, dass es Unit-Tests schwierig machen wird. Einige der Logikfunktionen können mehr als 100 verschiedene Suchvorgänge ausführen. Während ich definitiv ein verspottbares Objekt machen kann, das unsere Preise zurückgibt, wird es ein beträchtliches Setup geben. Ich denke, es ist entweder das oder ich muss am Ende Integrationstests verwenden (und diese Datenbank treffen). Habe ich recht oder gibt es einen besseren Weg? Irgendwelche Vorschläge?
Bearbeiten:
Entschuldigung für die verspätete Antwort, aber ich habe versucht, alles in mich aufzunehmen, während ich gleichzeitig mit vielen anderen Dingen jonglierte. Ich wollte auch versuchen, die Implementierung durchzuarbeiten und gleichzeitig. Ich habe verschiedene Muster ausprobiert, um die Lösung für etwas zu finden, mit dem ich zufrieden war. Ich habe das Besuchermuster ausprobiert, mit dem ich nicht zufrieden war. Am Ende habe ich die Zwiebelarchitektur verwendet. War ich mit den Ergebnissen zufrieden? Art von. Ich denke es ist was es ist. Die Nachschlagetabellen machen es viel schwieriger.
Hier ist ein kleines Beispiel (ich verwende fakeiteasy) des Setup-Codes für die Tests für eine Rate, die sich jährlich ändert:
private void CreateStubsForCrsOS39Int()
{
CreateMacIntStub(0, 1.00000m);
CreateMacIntStub(1, 1.03000m);
CreateMacIntStub(2, 1.06090m);
CreateMacIntStub(3, 1.09273m);
CreateMacIntStub(4, 1.12551m);
CreateMacIntStub(5, 1.15928m);
CreateMacIntStub(6, 1.19406m);
CreateMacIntStub(7, 1.22988m);
CreateMacIntStub(8, 1.26678m);
CreateMacIntStub(9, 1.30478m);
CreateMacIntStub(10, 1.34392m);
CreateMacIntStub(11, 1.38424m);
CreateMacIntStub(12, 1.42577m);
CreateMacIntStub(13, 1.46854m);
CreateMacIntStub(14, 1.51260m);
CreateMacIntStub(15, 1.55798m);
CreateMacIntStub(16, 1.60472m);
CreateMacIntStub(17, 1.65286m);
CreateMacIntStub(18, 1.70245m);
CreateMacIntStub(19, 1.75352m);
CreateMacIntStub(20, 1.80613m);
CreateMacIntStub(21, 1.86031m);
CreateMacIntStub(22, 1.91612m);
CreateMacIntStub(23, 1.97360m);
CreateMacIntStub(24, 2.03281m);
CreateMacIntStub(25, 2.09379m);
CreateMacIntStub(26, 2.15660m);
CreateMacIntStub(27, 2.24286m);
CreateMacIntStub(28, 2.28794m);
CreateMacIntStub(29, 2.35658m);
CreateMacIntStub(30, 2.42728m);
CreateMacIntStub(31, 2.50010m);
CreateMacIntStub(32, 2.57510m);
CreateMacIntStub(33, 2.67810m);
CreateMacIntStub(34, 2.78522m);
CreateMacIntStub(35, 2.89663m);
CreateMacIntStub(36, 3.01250m);
CreateMacIntStub(37, 3.13300m);
CreateMacIntStub(38, 3.25832m);
CreateMacIntStub(39, 3.42124m);
CreateMacIntStub(40, 3.59230m);
CreateMacIntStub(41, 3.77192m);
CreateMacIntStub(42, 3.96052m);
CreateMacIntStub(43, 4.19815m);
CreateMacIntStub(44, 4.45004m);
CreateMacIntStub(45, 4.71704m);
CreateMacIntStub(46, 5.00006m);
CreateMacIntStub(47, 5.30006m);
CreateMacIntStub(48, 5.61806m);
CreateMacIntStub(49, 5.95514m);
CreateMacIntStub(50, 6.31245m);
CreateMacIntStub(51, 6.69120m);
CreateMacIntStub(52, 7.09267m);
CreateMacIntStub(53, 7.51823m);
CreateMacIntStub(54, 7.96932m);
CreateMacIntStub(55, 8.44748m);
CreateMacIntStub(56, 8.95433m);
CreateMacIntStub(57, 9.49159m);
CreateMacIntStub(58, 10.06109m);
CreateMacIntStub(59, 10.66476m);
CreateMacIntStub(60, 11.30465m);
CreateMacIntStub(61, 11.98293m);
CreateMacIntStub(62, 12.70191m);
CreateMacIntStub(63, 13.46402m);
CreateMacIntStub(64, 14.27186m);
CreateMacIntStub(65, 15.12817m);
CreateMacIntStub(66, 16.03586m);
CreateMacIntStub(67, 16.99801m);
CreateMacIntStub(68, 18.01789m);
CreateMacIntStub(69, 19.09896m);
CreateMacIntStub(70, 20.24490m);
CreateMacIntStub(71, 21.45959m);
CreateMacIntStub(72, 22.74717m);
CreateMacIntStub(73, 24.11200m);
CreateMacIntStub(74, 25.55872m);
CreateMacIntStub(75, 27.09224m);
CreateMacIntStub(76, 28.71778m);
}
private void CreateMacIntStub(byte numberOfYears, decimal returnValue)
{
A.CallTo(() => _macRateRepository.GetMacArIntFactor(numberOfYears)).Returns(returnValue);
}
Hier ist ein Setup-Code für einen Zinssatz, der sich jederzeit ändern kann (es kann Jahre dauern, bis ein neuer Zinssatz eingeführt wird):
private void CreateStubForGenMbrRateTable()
{
_rate = A.Fake<IRate>();
A.CallTo(() => _rate.GetRateFigure(17, A<System.DateTime>.That.Matches(x => x < new System.DateTime(1971, 7, 1)))).Returns(1.030000000m);
A.CallTo(() => _rate.GetRateFigure(17,
A<System.DateTime>.That.Matches(x => x < new System.DateTime(1977, 7, 1) && x >= new System.DateTime(1971,7,1)))).Returns(1.040000000m);
A.CallTo(() => _rate.GetRateFigure(17,
A<System.DateTime>.That.Matches(x => x < new System.DateTime(1981, 7, 1) && x >= new System.DateTime(1971, 7, 1)))).Returns(1.050000000m);
A.CallTo(
() => _rate.GetRateFigure(17, A<System.DateTime>.That.IsGreaterThan(new System.DateTime(1981, 6, 30).AddHours(23)))).Returns(1.060000000m);
}
Hier ist der Konstruktor für eines meiner Domänenobjekte:
public abstract class OsEarnDetail: IOsCalcableDetail
{
private readonly OsEarnDetailPoco _data;
private readonly IOsMacRateRepository _macRates;
private readonly IRate _rate;
private const int RdRate = (int) TRSEnums.RateTypeConstants.ertRD;
public OsEarnDetail(IOsMacRateRepository macRates,IRate rate, OsEarnDetailPoco data)
{
_macRates = macRates;
_rate = rate;
_data = data;
}
Warum mag ich es nicht? Gut vorhandene Tests werden funktionieren, aber jeder, der in Zukunft neue Tests hinzufügt, muss diesen Setup-Code durchsehen, um sicherzustellen, dass neue Raten hinzugefügt werden. Ich habe versucht, es so klar wie möglich zu machen, indem ich den Tabellennamen als Teil des Funktionsnamens verwendet habe, aber ich denke, es ist das, was es ist :)