How to make linker prefer implementation from a given location
I need a way to make linker prefer one implementation instead of another. My use case is the following: I'm writing unit tests, and I need to mock some objects. 开发者_开发知识库The problem is those objects are in 'main' library, which I cannot throw away even in debug, because many of SDK things live there.
So I've implemented those mocks, but now it seems that linker prefers implementation from the 'main' library, at least my code is not called. I'm using ARM RVCT 4 C++ compiler with Symbian toolchain, if this is important.
Any ideas (even workarounds) are greatly appreciated!
EDIT: I need to mock static method call, and probably it is important, as I think static methods are linked in some other ways compared to ordinary methods.
Usually mocking isn't done on linking stage but is solved in your code. Dependency Injection is one of the preferred techniques. That is, you are supposed to model your code so you can choose between a real and mock implementation.
For example you want to create an object A in your code. One way is to have two different implementations of A and link to the mocking implementation when you build your tests. Dependency Injection approach suggest having a pointer to an interface and pass from outside (e.g., in the constructor) the object itself. Then, from the production code you will pass the real object and from the unit test you will pass the mock.
If you absolutely need to do it on link level and you cannot avoid linking the "real" objects, then can you wrap these objects? Here's an example:
Suppose this is the code you want to test:
void my_method()
{
ProblematicClass c;
c.Call();
}
ProblematicClass
is implemented in two places: one inside the SDK another is your mock. If you can wrap ProblematicClass
inside another class, then you can create two source files:
Production file:
struct Wrapper
{
public:
void Call() { m.Call(); }
private:
ProblematicClass m;
}
Mock file:
struct Wrapper
{
public:
void Call() { m.Call(); }
private:
MockClass m;
}
Now the sources are in your control, you don't have to change the design of your tested code and you can exclude the production implementation. Your tested code of course has to change to:
void my_method()
{
Wrapper c;
c.Call();
}
I'm not sure I understand exactly what your problem is, but it might be worth checking out the documentation for $sub$$
and $super$$
: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0206j/Chdefdce.html.
精彩评论