InterfaceTests
Содержание
Написание тестов для проверки существования (отсутствия) интерфейсов.
Часто при отладке программы появляются сообщения вида:
fixme:shdocvw:WebBrowser_QueryInterface (0x3199770)->({00000019-0000-0000-c000-000000000046} 0x32ed80) interface not supported
Возникают подозрения, что программа может не работать из за отсутствия данного интерфеса.
Чтобы убрать это сообщение необходимо проверить должен ли возвращаться интерфейс из этого места. И если нет, то изменить FIXME на TRACE о том, что интерфейс не поддерживается.
Написание теста на неподдерживаемый интерфейс
Изначально предполагаем что интерфейс не поддерживается.
В тестах для данной dll должен быть файл с названием объекта, откуда и запрашивается интерфейс. В данном случае это dlls/shdocvw/tests/webbrowser.c
Там должна быть функция test_QueryInterface, в которой и находятся тесты на неподдерживаемые интерфейсы.
Добавляемый тест выглядит следующим образом:
hres = IUnknown_QueryInterface(unk, &IID_IExternalConnection, (void**)&viewex); ok(hres == E_NOINTERFACE, "QueryInterface returned %08x, expected E_NOINTERFACE\n", hres); ok(viewex == NULL, "viewex=%p, expected NULL\n", viewex);
Написание теста на поддерживаемый интерфейс
Если тест показал, что интерфес всё же поддерживается. То придётся удалить этот тест, и добавить тест, показывающий, что интерфейс поддерживается.
Он будет выглядеть следующим образом (пример другого интерфейса, запрашиваемого из другого места):
void test_IPersistHistory()
{
HRESULT hres;
IUnknown *unk;
LONG ref;
IPersistHistory *phist;
hres = create_document(&unk);
if(FAILED(hres))
return;
hres = IUnknown_QueryInterface(unk, &IID_IPersistHistory, (void**)&phist);
todo_wine ok(hres == S_OK, "QueryInterface returned %08x, expected S_OK\n", hres);
if(hres == S_OK)
IPersistHistory_Release(phist);
ref = IUnknown_Release(unk);
ok(ref == 0, "ref=%d, expected 0\n", ref);
}
Доработка QueryInterface
Если интерфейс не поддерживается, то добавляем в соответсвующую функцию вызова (в данном случае это :Web Browser_ Query Interface) в соответствующее место TRACE:
}else if(IsEqualGUID(&IID_IExternalConnection, riid)) {
TRACE("(%p)->(IID_IExternalConnection %p) returning NULL\n", This, ppv);
return E_NOINTERFACE;
}
Если интерфейс всё-же поддерживается то добавляется (в данном случае в HTMLDocument_QueryInterface):
}else if(IsEqualGUID(&IID_IPersistHistory, riid)) {
FIXME("(%p)->(IID_IPersistHistory currently not supported %p)\n", This, ppvObject);
*ppvObject = NULL;
Это для начала. А вообще хорошо бы в этом местре реализовать правильный возврат интерфейса.
Например:
}else if(IsEqualGUID(&IID_IOleObject, riid)) {
TRACE("(%p)->(IID_IOleObject %p)\n", This, ppv);
*ppv = OLEOBJ(This);