【问题标题】:Memory issues when using spring.Nullable with DUnitX将 spring.Nullable 与 DUnitX 一起使用时的内存问题
【发布时间】:2018-11-28 12:44:00
【问题描述】:

最近在我的公司,我们尝试使用 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 单元中的 Move 过程,TValueDataImpl.ExtractRawDataNoCopy 函数: 当 Length(FData) 小于或等于 8 时,它工作正常 当 Length(FData) 在 System 单元 (FISTP QWORD PTR [EDX+8] {Save Second 8}) 的第 5905 行的 9 到 32 之间时,整个调用堆栈消失在两行旁边(我们不确定它是否相关,但它看起来不是好兆头) 并在到达最顶层函数后(根据调用堆栈)我们得到错误。

Call stack before "saving second 8"

Call stack after "saving second 8"

是我们的错还是 system/spring/dunitx 单元有问题?我们如何同时使用可空类型和测试?

【问题讨论】:

    标签: delphi-10.1-berlin spring4d dunitx


    【解决方案1】:

    我不确定 Delphi Mocks 是否在其 WillReturn 方法上有一个泛型类型参数,但如果有,则将 TNullableCurrency 传递到那里 - 否则编译器将根据您传递的参数 2 推断类型,显然是在内部传递它未能将其放入应该返回的TNullableCurrency

    如果它不允许并且只允许TValue,那么您需要传递一个包含TNullableCurrency 而不是2 的值,它可以使用其隐式运算符,如下所示:TValue.From&lt;TNullableCurrency&gt;(2)

    此外,当要比较的值是记录时(如 TNullableCurrency 那样),我不确定他们是否修复了 Delphi Mocks 中 SameValue 例程中的代码

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

    您可能想考虑尝试一下 Spring4D 模拟,它应该能够处理可空值。

    【讨论】:

    • 关于传递给 WillReturn 的参数 - 我们已经编写了强制转换,所以它不会成为问题。感谢您提供的链接,我们更改了 Mocks 单元并使用 Rtti 来查找 Equal 类运算符 nad 通过这样做,我们能够以我们想要的方式比较这些值。
    猜你喜欢
    • 2019-02-26
    • 2012-03-28
    • 2016-11-10
    • 2020-08-23
    • 1970-01-01
    • 1970-01-01
    • 2021-08-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多