You can't "redefine" these things per se, but you can provide an alternative implementation under a different name, and make the distinction almost transparent in your real code.
Typically, you mock the function.
CxxTest takes the approach of having you invoke T::time()
instead of std::time()
(which is close enough!); with macro/include tricks, that call will resolve either to std::time()
or to whatever replacement implementation you provide.
Here's a much-simplified, incredibly naive example designed only to demonstrate the basic principle:
foo.h
#include "mocked-functions.h"
/**
* Takes the current time as a UNIX timestamp, and divides it by 10.
*/
inline int foo()
{
return T::time(NULL) / 10;
}
main.cpp
#include "foo.h"
#include <iostream>
int main()
{
std::cout << foo() << std::endl;
}
test.cpp
#define USE_MOCKS
#include "foo.h"
#include <cassert>
int main()
{
mock_time_result = 50;
assert(foo() == 5);
mock_time_result = 400;
assert(foo() == 40);
}
mocked-functions.h
#include <ctime>
#ifdef USE_MOCKS
#include "mock-time.h"
#endif
namespace T {
time_t time(time_t* ptr)
{
#ifdef USE_MOCKS
return Mock_time(ptr);
#else
return std::time(ptr);
#endif
}
}
mock-time.h
#include <ctime>
time_t mock_time_result = 0;
time_t Mock_time(time_t* ptr)
{
if (ptr) *ptr = mock_time_result
return mock_time_result;
}
To run
$ g++ main.cpp -I. -o main
$ g++ test.cpp -I. -o test
$ ./main # output is the real time div by 10
$ ./test # output is nothing; all assertions succeed