Injector++ is a library to help you fake virtual/non-virtual methods, static methods and global functions WITHOUT changing existing code.
- Injector++ needs to retrieve information from pdb, therefore please:
- In Visual Studio, open project property dialog, select Configuration Properties -> Linker -> Debugging, change
Generate Debug Info
toDebug
. - Add
dbgHelp.lib
as dependency in your test project setting. - Project property dialog -> Linker -> General -> Enable Incremental Linking ->
No (/INCREMENTAL:NO)
.
In progress.
In progress.
Below example fakes fooReturnString
by using fakeFooReturnString
:
std::string fooReturnString()
{
return "FooReturnString";
}
std::string fakeFooReturnString()
{
return "FakeFooReturnString";
}
TEST_F(FakeClassNonVirtualMethodTestFixture, FakeGlobalStringFunctionWhenCalled)
{
// Prepare
std::string expected = "FakeFooReturnString";
InjectorPP::Injector injector;
injector.whenCalled(fooReturnString)
.willExecute(fakeFooReturnString);
// Act
// fakeFooReturnString will be executued!
std::string actual = fooReturnString();
// Assert
EXPECT_EQ(expected, actual);
}
Below example fakes BaseClassTest::getAnInteger()
by using fakeFunc()
:
class FakeClassNonVirtualMethodTestFixture : public ::testing::Test
{
public:
int fakeFunc()
{
return 6;
}
};
TEST_F(FakeClassNonVirtualMethodTestFixture, FakeIntFunctionWhenCalled)
{
// Prepare
int expected = 6;
InjectorPP::Injector injector;
injector.whenCalled(INJECTORPP_MEMBER_FUNCTION(BaseClassTest::getAnInteger))
.willExecute(INJECTORPP_MEMBER_FUNCTION(FakeClassNonVirtualMethodTestFixture::fakeFunc));
BaseClassTest b = BaseClassTest();
// Act
// fakeFunc will be executed!
int actual = b.getAnInteger();
// Assert
EXPECT_EQ(expected, actual);
}
Injector++ supports virtual method mocking (Amazing, huh?). Below is a simple example:
int fakeIntFuncForDerived()
{
return 2;
}
TEST_F(FakeClassVirtualMethodTestFixture, MockDerivedClassVirtualMemberFunctionWhenCalled)
{
// Prepare
int expected = 2;
BaseClassTest* derived = new SubClassTest();
InjectorPP::Injector injector;
injector.whenCalledVirtualMethod(derived, "getAnIntegerVirtual")
.willExecute(fakeIntFuncForDerived);
// Act
// fakeIntFuncForDerived() will be exectued!
int actual = derived->getAnIntegerVirtual();
// Assert
EXPECT_EQ(expected, actual);
delete derived;
derived = NULL;
}
Injector++ supports static method mocking. Below is a simple example:
static Address fakeGetAnAddressStatic()
{
Address addr;
addr.setAddressLine("fakeAddressLine");
addr.setZipCode("fakeZipCode");
return addr;
}
TEST_F(FakeClassNonVirtualMethodTestFixture, FakeStaticFunctionReturnUserDefinedClassWhenCalled)
{
// Prepare
Address expected;
expected.setAddressLine("fakeAddressLine");
expected.setZipCode("fakeZipCode");
InjectorPP::Injector injector;
injector.whenCalled(INJECTORPP_STATIC_MEMBER_FUNCTION(BaseClassTest::getAnAddressStatic))
.willExecute(INJECTORPP_MEMBER_FUNCTION(FakeClassNonVirtualMethodTestFixture::fakeGetAnAddressStatic));
// Act
// fakeGetAnAddressStatic will be executed!
Address actual = BaseClassTest::getAnAddressStatic();
// Assert
EXPECT_EQ(expected, actual);
}
There's a headache of C++ unit testing - No way to abstract the legacy code. As there's no reflection in C++, it is not that easy to change the behavior of non-virtual and static methods, which makes C++ unit testing extremely hard.
Injector++ intends to resolve the headache. Its goal is to make static method, non-virtual method and global functions testable without changing your production code. To accomplish this we still have to:
- Add rich mock helper functions (e.g, return value expectation, input parameter mock, exception expectation...).
- Add Linux support.
- Adapt to mainstream unit test runners.
Welcome to help Injector++. You can submit bugs, suggestions and feature requests to the issue tracker, or send me pull request. Happy coding & testing!
You need following prerequisites:
- cmake 2.6+
- Visual Studio 2008+ (Please create an issue if you need older MSVC support)
Run .\build.cmd
to full build the source code as well as running tests.
Run .\build.cmd /f
to clean the build directory and rebuild all the source code and running tests.
Run .\build.cmd /skiptests
if you want build source code without building and running tests.
You can combine /f
and /skiptests
:
.\build.cmd /f /skiptests
After build finished, you'll find injectorpp.sln
under build
folder. You can use Visual Studio to edit and debug the code.
In progress.
In progress.