class A{
public:
A() : Alpha(0), Aleph(0){}
void setAlpha(const int a) { Alpha = a; }
void setAleph(const int a) { Aleph = a; }
int alpha() const { return Alpha; }
int aleph() const { return Aleph; }
private:
int Alpha, Aleph;
}
Suppose I have the above class with setters and getters (a simplified case of what I'm working with at the moment)
Suppose I wish to unit test these.
I could write
TEST(ATests, Alpha){
A alex;
alex.setAlpha(1234);
EXPECT_EQ(1234, alex.alpha)
}
TEST(ATests, Aleph){
A alex;
alex.setAleph(1234);
EXPECT_EQ(1234, alex.aleph)
}
But if I have many member variables, these tests can become tedious. Especially if other things occur, like Qt Signal emission when Alpha or Aleph changes, incurring new tests around the changes, or accessing the value through the Qt Property system instead of the standard set/get.
what I would like to be able to do is something like the following: (note, this uses c++11, but I think it should be possible without that standard as well, but more complicated to set up)
#include <list>
#include <tuple>
#include <functional>
using std::list;
using std::tuple;
using std::function;
typedef tuple<function<void(int)>, function<int()> > ATestTuple_t;
typedef list<ATestTuple_t> ATestList_t;
using std::placeholders::_1;
class ATestData {
public:
ATestData(A* testObject){
testDataList.emplaceLast(std::bind(&A::setAlpha, testObject, _1),
std::bind(&A::alpha, testObject, _1));
testDataList.emplaceLast(std::bind(&A::setAleph, testObject, _1),
std::bind(&A::aleph, testObject, _1));
}
ATestList_t testDataList;
}
using ::testing::Test;
class ATests : public Test{
protected:
void SetUp(){
TestData = new ATestData(&TestObject);
}
void TearDown(){
delete TestData; TestData = nullptr;
}
A TestObject;
ATestData* TestData;
const int ExpectedValue = 1234;
}
class A_ParamTests : public ATests, public ::testing::WithParamInterface<ATestTuple_T>{
protected:
void SetUp(){
ATests::SetUp();
ATestTuple_T testTuple = GetParam();
setter = std::get<0>(testTuple);
getter = std::get<1>(testTuple);
}
function<void(int)> setter;
function<int(void)> getter;
};
TEST_P(A_ParamTests, tests){
setter(ExpectedValue);
EXPECT_EQ(ExpectedValue, getter());
}
INSTANTIATE_TEST_CASE_P(SetGetParamTests, A_ParamTests, ::testing::ValuesIn(TestData.testDataList))
I know it's a lot of code, but hopefully you can see what I'm getting at. If I can have
functions in my test parameters, then I can rapidly test a whole lot of functions that do more or less the same thing, but have varying, correlated, names.
--------------------------
For instance, in my real world example, I have a class inheriting from QObject with QProperty values, and notification signals when the value changes. So, for each property there are 5 tests:
- use setter, expect change signal emitted
- use setter twice with same value, expect change signal emitted only once
- use setProperty("propertyName"), expect change signal
- use getter to confirm it matches set value
- use property("propertyName") to confirm matches set value
One of my classes has 7 properties. That's 7 x 5 tests whose only real variation is the specific name of the function to use to set the value or get the value.
If I had each of those tests parameterized on the function rather than parameters to be passed to a function, That would simplify the test code greatly.