最近、私の会社で、私たちが書いたクラスをテストするために、DUnitX を使用しようとしました。これらのクラスはデータベース内のエンティティを反映するため、すべてのフィールドは null 値と特定の型 (整数や文字列など) を受け入れる必要があります。
spring4d にはすでにそれらを使用しようとしたものがあるため、次のようにします。
INaleznosc = interface
['{D5D6C901-3DB9-4EC2-8070-EB0BEDBC7B06}']
function DajPodstawaVAT(): TNullableCurrency;
property PodstawaVAT: TNullableCurrency read DajPodstawaVAT;
end;
TNaleznosc = class(TInterfacedObject, INaleznosc)
strict private
FId: TNullableInt64;
FPodstawaVAT: Currency;
function TNaleznosc.DajPodstawaVAT(): TNullableCurrency;
published
property PodstawaVAT: TNullableCurrency read DajPodstawaVAT;
end;
INaleznoscFunkcje = interface
['{509288AB-110A-4A52-BE93-3723E5725F4B}']
function DajPodstawaVAT(pID: TNullableInt64): TNullableCurrency;
end;
function TNaleznosc.DajPodstawaVAT(): TNullableCurrency;
begin
FPodstawaVAT := FFunkcje.DajPodstawaVAT(FId);
end;
procedure TTestNaleznosc.PodstawaVATGetterNieWywolujefunkcji();
var
funkcjeNaleznosc: TMock<INaleznoscFunkcje>;
klasa: INaleznosc;
id: TNullableInteger;
begin
//initialize tested elements
funkcjeNaleznosc := TMock<INaleznoscFunkcje>.Create();
id := 15;
klasa := TNaleznosc.Create(funkcjeNaleznosc, id, zmienne);
//setup expected behaviour from mock
funkcjeNaleznosc.Setup.WillReturn(2).When.DajPodstawaVAT(id);
funkcjeNaleznosc.Setup.Expect.Once.When.DajPodstawaVAT(id);
//this triggers getter
klasa.PodstawaVAT;
end;
このコードが実行されると、 AV 例外が発生しFirst chance exception at $00000000. Exception class $C0000005 with message 'access violation at 0x00000000: access of address 0x00000000'. Process Tests.exe (6556)
ます。
System.Rtti
最終的に、この問題をユニット内の関数の移動プロシージャに絞り込みましたTValueDataImpl.ExtractRawDataNoCopy
。Length(FData) が 8 以下の場合、System
ユニット ( FISTP QWORD PTR [EDX+8] {Save Second 8}
) の 5905 行で Length(FData) が 9 ~ 32 の場合、正常に動作します。コール スタック全体が横に消えます。 2行(関連性があるかどうかはわかりませんが、良い兆候のようには見えません)、(コールスタックによると)最上位の関数に到達した後、エラーが発生します.
それは私たちのせいですか、それともシステム/スプリング/dunitx ユニットの問題ですか? null 許容型とテストを同時に使用するにはどうすればよいですか?