Hi. I am struggling with replacing a real function with a mock.
I have two compilation units written in C, that I would like to test.
One of them uses the other one, and in that one I would like to switch between the original function and the mock during the test.
My two modules are mocked like this:
calculus.hpp:
#ifndef CALCULUS_MOCK_H
#define CALCULUS_MOCK_H
struct calculus {
static double (*add)(double a, double b);
static double (*subtract)(double a, double b);
static void (*printstuff)();
};
extern "C"
{
#include "../source/calculus.h"
}
namespace Fake
{
double add(double x, double y);
double subtract(double x, double y);
void printstuff();
}
namespace Real
{
double add(double x, double y);
double subtract(double x, double y);
void printstuff();
}
#endif
calculus.cpp:
#include "CppUTest/TestHarness.h"
#include "CppUTestExt/MockSupport.h"
#include "calculusmock.hpp"
#include <stdio.h>
namespace Real
{
#include "../source/calculus.c"
}
namespace Fake
{
double add(double x, double y)
{
printf("add mocked \n");
return double(mock().actualCall(__func__)
.withParameter("x", x)
.withParameter("y", y)
.returnDoubleValue());
}
double subtract(double x, double y)
{
printf("subtract mocked \n");
return double(mock().actualCall(__func__)
.withParameter("x", x)
.withParameter("y", y)
.returnDoubleValue());
}
void printstuff()
{
printf("printstuff mocked \n");
mock().actualCall(__func__);
}
}
/** Initialization of function pointers
*/
double (*calculus::add)(double a, double b) = Real::add;
double (*calculus::subtract)(double a, double b) = Real::subtract;
void (*calculus::printstuff)() = Real::printstuff;
/** Wrappers to be linked in place of original functions
*/
extern "C" double add(double a, double b)
{
printf("add wrapped \n");
return calculus::add(a, b);
}
extern "C" double subtract(double a, double b)
{
printf("subtract wrapped \n");
return calculus::subtract(a, b);
}
extern "C" void printstuff()
{
printf("printstuff wrapped \n");
return calculus::printstuff();
}
domath.hpp:
#ifndef DOMATH_MOCK_H
#define DOMATH_MOCK_H
struct domath {
static double (*showmath)(double x, double y);
static void* (*leak)();
static void (*crash)();
};
extern "C"
{
#include "../source/domath.h"
}
namespace Fake
{
double showmath(double x, double y);
void* leak();
void crash();
}
namespace Real
{
double showmath(double x, double y);
void* leak();
void crash();
}
#endif
domath.cpp:
#include "CppUTest/TestHarness.h"
#include "CppUTestExt/MockSupport.h"
#include "domathmock.hpp"
#include "calculusmock.hpp"
#include <stdio.h>
namespace Real
{
#include "../source/domath.c"
}
namespace Fake
{
double showmath(double x, double y)
{
printf("showmath mocked \n");
return double(mock().actualCall(__func__)
.withParameter("x", x)
.withParameter("y", y)
.returnDoubleValue());
}
void* leak()
{
printf("leak mocked \n");
mock().actualCall(__func__);
}
void crash()
{
printf("crash mocked \n");
mock().actualCall(__func__);
}
}
/** Initialization of function pointers
*/
double (*domath::showmath)(double x, double y) = Real::showmath;
void* (*domath::leak)() = Real::leak;
void (*domath::crash)() = Real::crash;
/** Wrappers to be linked in place of original functions
*/
extern "C" double showmath(double x, double y)
{
printf("showmath wrapped \n");
return domath::showmath(x, y);
}
extern "C" void* leak() {
return domath::leak();
}
extern "C" void crash() {
return domath::crash();
}
When I run the following test, showmath() is called through the wrapper but printstuff does not. Why is that?
domathtest.cpp:
#include "CppUTest/TestHarness.h"
#include "CppUTestExt/MockSupport.h"
#include <stdio.h>
#include "../mock/calculusmock.hpp"
#include "../mock/domathmock.hpp"
TEST_GROUP(math)
{
void setup()
{
UT_PTR_SET(domath::showmath, Real::showmath);
UT_PTR_SET(domath::leak, Real::leak);
UT_PTR_SET(domath::crash, Real::crash);
UT_PTR_SET(calculus::add, Fake::add);
UT_PTR_SET(calculus::subtract, Fake::subtract);
UT_PTR_SET(calculus::printstuff, Fake::printstuff);
}
void teardown()
{
mock().clear();
}
};
TEST(math, domath)
{
printf("domath \n");
mock().expectNCalls(2, "printstuff");
printstuff();
mock().expectOneCall("add")
.withParameter("x", 25.0)
.withParameter("y", 25.0)
.andReturnValue(5.0f);
mock().expectOneCall("subtract")
.withParameter("x", 35.0)
.withParameter("y", 35.0)
.andReturnValue(15.0f);
// act
double sum = showmath(25, 25);
// assert
DOUBLES_EQUAL(5, sum, 0.01);
mock().checkExpectations();
}
TEST(math, leak)
{
//leak();
}
TEST(math, crash)
{
//crash();
}
My test main looks like this:
#include "CppUTest/CommandLineTestRunner.h"
int main(int ac, char** av)
{
MemoryLeakWarningPlugin::turnOnThreadSafeNewDeleteOverloads();
//MemoryLeakWarningPlugin::turnOffNewDeleteOverloads();
return CommandLineTestRunner::RunAllTests(ac, av);
}