Как сделать так, чтобы компоновщик предпочитал реализацию из заданного местоположения

Мне нужен способ, чтобы компоновщик предпочитал одну реализацию вместо другой. Мой пример использования следующий: я пишу модульные тесты, и мне нужно смоделировать некоторые объекты. Проблема в том, что эти объекты находятся в "основной" библиотеке, которую я не могу выбросить даже при отладке, потому что многие вещи из 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.

Другие вопросы по тегам