Проблемы с памятью при использовании 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, чтобы они могли обрабатывать обнуляемые значения.