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);