void.pointer
void.pointer

Reputation: 26395

How to mock classes already compiled into a library?

Our code base has a collection of components. Each component contains "common"/reusable code in the form of independent projects built into static libraries. Examples of components: UI Widgets, Containers, Networking, etc.

When I write a unit test for our UI widgets, I am actually building an executable that links against the "UI Widgets" static library.

When it comes to mocking, this makes things complicated. Normal mocking methods I've read about (dependency injection / inversion of control) are demonstrated in such a way that seems difficult (if not impossible) to do when the code being mocked has already been compiled.

If my UI Widgets static library contains the implementation of about 20 classes, I might only need to mock 5 of those. So I need to somehow tell my test executable to use 15 symbols from the static lib but ignore 5 (and favor the mocked implementations in either another library or ideally compiled into the test executable directly).

How can I mock classes in a static library effectively? I can think of some ways to do it by using runtime polymorphism + interface pattern, however I'd love to be able to mock using templates as well. Using templates seems more out of reach for me here just based on the structure of my projects.

Upvotes: 1

Views: 413

Answers (1)

Al.exe
Al.exe

Reputation: 483

Disclaimer I work at Typemock.

Using templates and polymorphism for "mocking" forces you to adapt your production code to to your tests, for instance adding redundant levels of indirection and use of interfaces in places where you normally would not do it, sometimes breaking your original design.

Introduces new classes and interfaces (that require maintenance), eventually complicates your code by making your code larger, less readable and not as straightforward as you'd like it to be.

Typemock Isolator++ solves this issue by enabling you to mock ANYTHING(*abstract classes, non virtual, static, non public, c functions etc...) in runtime, inside you tests in a library separate from your production code.

No risk of breaking your production code when refactoring it to be more testable.

For Example:

class MyClass
{
   int GetResult() { return -1; }
}

Is faked the following way:

MyClass* fakeMyClass = FAKE<MyClass>();
WHEN_CALLED(fakeMyClass->GetResult()).Return(10);

See more examples.

Upvotes: 2

Related Questions