Я пытаюсь запустить модульный тест GUI с DUnit для приложения, основная форма которого динамически создает для себя фреймы. Мне удалось создать основную форму приложения для тестирования как форму в тестовом примере и получить доступ к ее пунктам меню и т. Д.
Проблема возникает, когда приложение пытается создать фрейм динамически. Чтение ресурса фрейма доходит до того, что ему нужен дескриптор окна (в моем случае установка заголовка вкладки). Здесь он переходит от TWinControl.GetHandle к TWinControl.CreateWnd и к TCustomFrame.CreateParams.
В этом CreateParams код говорит:
if Parent = nil then
Params.WndParent := Application.Handle;
Вот где и проявляется разница. Когда я запускаю реальное приложение (не в тесте), Application.Handle здесь возвращает ненулевое число, и поток продолжается нормально. Но в тестовом приложении DUnit Application.Handle здесь возвращает 0. Это приводит к тому, что код в TWinControl.CreateWnd вызывает исключение, сообщающее, что у кадра нет родителя:
with Params do
begin
if (WndParent = 0) and (Style and WS_CHILD <> 0) then
if (Owner <> nil) and (csReading in Owner.ComponentState) and
(Owner is TWinControl) then
WndParent := TWinControl(Owner).Handle
else
raise EInvalidOperation.CreateFmt(SParentRequired, [Name]);
Я бы хотел попытаться обойти эту проблему (и в целом все тестовые задачи), не изменяя "производственный" код только из-за тестов. Не могли бы вы подсказать, могу ли я каким-то образом принудить «Приложение» к чему-то другому или каким-то другим способом обойти это?
Глядя на код, другой возможный сценарий обхода может заключаться в том, чтобы попытаться заставить владельца (которым является моя «MainForm» тестируемого приложения, то есть чей дескриптор я хотел бы получить) находиться в состоянии csReading при выполнении это создание кадра в тесте, но, по крайней мере, поначалу это не кажется таким уж простым, чтобы это произошло.
TApplication
создает свой дескриптор в своем конструкторе, покаIsLibrary
ложно. Это означает, что DUnit либо ошибочно устанавливаетIsLibrary
, что ваш код находится в DLL, либо DUnit перезаписываетApplication.Handle
перед запуском вашего кода. - person Rob Kennedy   schedule 22.02.2012