Как сделать так, чтобы компоновщик предпочитал реализацию из заданного местоположения
Мне нужен способ, чтобы компоновщик предпочитал одну реализацию вместо другой. Мой пример использования следующий: я пишу модульные тесты, и мне нужно смоделировать некоторые объекты. Проблема в том, что эти объекты находятся в "основной" библиотеке, которую я не могу выбросить даже при отладке, потому что многие вещи из SDK живут там.
Я реализовал эти макеты, но теперь кажется, что компоновщик предпочитает реализацию из "основной" библиотеки, по крайней мере, мой код не вызывается. Я использую компилятор ARM RVCT 4 C++ с набором инструментов Symbian, если это важно.
Любые идеи (даже обходные пути) приветствуются!
РЕДАКТИРОВАТЬ: мне нужно смоделировать вызов статического метода, и, вероятно, это важно, так как я думаю, что статические методы связаны другими способами по сравнению с обычными методами.
2 ответа
Обычно на этапе компоновки не выполняется насмешка, а решается в вашем коде. Инъекция зависимости является одним из предпочтительных методов. То есть вы должны смоделировать свой код, чтобы вы могли выбирать между реальной и фиктивной реализацией.
Например, вы хотите создать объект A в своем коде. Одним из способов является создание двух разных реализаций A и ссылка на импровизированную реализацию при создании тестов. Подход Dependency Injection предполагает наличие указателя на интерфейс и передачу извне (например, в конструкторе) самого объекта. Затем из производственного кода вы пройдете реальный объект, а из модульного теста вы пройдете макет.
Если вам абсолютно необходимо сделать это на уровне ссылок и вы не можете избежать связывания "реальных" объектов, то можете ли вы обернуть эти объекты? Вот пример:
Предположим, это код, который вы хотите проверить:
void my_method()
{
ProblematicClass c;
c.Call();
}
ProblematicClass
реализован в двух местах: один внутри SDK, другой - ваша издевка. Если вы можете обернуть ProblematicClass
внутри другого класса вы можете создать два исходных файла:
Производственный файл:
struct Wrapper
{
public:
void Call() { m.Call(); }
private:
ProblematicClass m;
}
Макет файла:
struct Wrapper
{
public:
void Call() { m.Call(); }
private:
MockClass m;
}
Теперь источники находятся под вашим контролем, вам не нужно менять дизайн тестируемого кода и вы можете исключить производственную реализацию. Ваш проверенный код, конечно, должен измениться на:
void my_method()
{
Wrapper c;
c.Call();
}
Я не уверен, что точно понимаю, в чем ваша проблема, но, возможно, стоит проверить документацию $sub$$
а также $super$$
: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0206j/Chdefdce.html.