Проблемы с памятью при использовании spring.Nullable с DUnitX

Недавно в моей компании мы пытались использовать DUnitX со всеми его благословениями для тестирования классов, которые мы написали. Поскольку эти классы отражают сущности в базе данных, все поля должны принимать значения NULL, а также определенный тип (например, Integer или string).

Так как у 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),

В конце концов мы сузили эту проблему до процедуры Move в System.Rtti единица измерения, TValueDataImpl.ExtractRawDataNoCopy Функция: когда длина (FData) меньше или равна 8, она работает нормально, когда длина (FData) находится между 9 и 32 в строке 5905 System единица измерения (FISTP QWORD PTR [EDX+8] {Save Second 8}) весь стек вызовов исчезает рядом с двумя строками (мы не уверены, является ли он актуальным или нет, но это не выглядит хорошим знаком), и после перехода к самой верхней функции (согласно стеку вызовов) мы получаем ошибку.

Стек вызовов перед "сохранением секунд 8"

Стек вызовов после "сохранения второго 8"

Это наша ошибка или проблема с блоками system/spring/dunitx? Как мы можем использовать обнуляемые типы и тесты одновременно?

1 ответ

Решение

Я не уверен, что Delphi Mocks имеет параметр общего типа на WillReturn метод, но если так, то пройти TNullableCurrency там - иначе компилятор выведет тип из параметра 2 вы проходите и, очевидно, внутренне это не в состоянии положить это в TNullableCurrency это должно вернуться.

Если это не так и только позволяет TValue тогда вам нужно передать тот, который содержит TNullableCurrency и не 2 что было бы с помощью своего неявного оператора, например, так: TValue.From<TNullableCurrency>(2)

Кроме того, я не уверен, что они исправили код в SameValue подпрограмма в Delphi Mocks, когда сравниваемое значение является записью (как TNullableCurrency является)

Изменить: нет, они не сделали - см. https://github.com/VSoftTechnologies/Delphi-Mocks/issues/39

Возможно, вы захотите попробовать макеты Spring4D, чтобы они могли обрабатывать обнуляемые значения.

Другие вопросы по тегам