使用spring.Nullable与DUnitX时出现内存问题

时间:2018-06-19 13:59:20

标签: delphi-10.1-berlin spring4d dunitx

最近在我公司,我们尝试使用DUnitX来测试我们编写的类。由于这些类反映了数据库中的实体,因此所有字段都必须接受空值以及特定类型(例如整数或字符串)。

由于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函数的Move过程: 当Length(FData)小于或等于8时,它可以正常工作 当System单位(FISTP QWORD PTR [EDX+8] {Save Second 8}的第5905行的Length(FData)在9到32之间时,整个调用堆栈会在两行旁边消失(我们不确定是否相关,但是不正确)看起来像个好兆头),然后转到最高功能(根据调用堆栈),我们会收到错误消息。

Call stack before "saving second 8"

Call stack after "saving second 8"

是我们的错,还是系统/弹簧/ dunitx单元有问题?我们如何才能同时使用可为空的类型和测试?

1 个答案:

答案 0 :(得分:0)

我不确定Delphi Mocks是否在其WillReturn方法上具有泛型类型参数,但是如果是,则在其中传递TNullableCurrency-否则编译器将从参数2推断类型。您正在通过,显然在内部它无法将其放入应该返回的TNullableCurrency中。

如果它不允许并且仅允许TValue,则需要传递包含TNullableCurrency而不是2的内容,方法是使用其隐式运算符,例如:{{1 }}

此外,如果要比较的值是一条记录(例如TValue.From<TNullableCurrency>(2)),我不确定他们是否在Delphi Mocks的SameValue例程中修复了代码

编辑:不,他们没有-请参见https://github.com/VSoftTechnologies/Delphi-Mocks/issues/39

您可能要考虑尝试使用Spring4D模拟程序,该程序应该能够处理可为空的变量。