Specify constructor arguments for a Google test Fixture
Solution 1
As suggested by another user, you cannot achieve what you want
by instantiating a fixture using a non-default constructor. However,
there are other ways. Simply overload the SetUp
function and
call that version explicitly in the tests:
class TheClassTest : public ::testing::Test {
protected:
TheClassTest() {}
virtual ~TheClassTest() {}
void SetUp(const std::string &filename) {
data = new TheClassData(filename);
tc = new TheClass(data);
}
virtual void TearDown() {
delete tc;
delete data;
}
TheClassData* data;
TheClass* tc;
};
Now in the test simply use this overload to set up filename:
TEST_F(TheClassTest, MyTestCaseName)
{
SetUp("my_filename_for_this_test_case");
...
}
The parameterless TearDown
will automatically clean up when
the test is complete.
Solution 2
Use the current class as a base class for your fixtures:
class TheClassTestBase : public ::testing::Test {
protected:
TheClassTestBase(std::string filename) : datafile(filename) {}
...
};
For every specific filename - use derived fixture:
class TheClassTestForFooTxt : public TheClassTestBase {
protected:
TheClassTestForFooTxt() : TheClassTestBase ("foo.txt") {}
};
However this is extra step needed for every set of parameters - so you can try to use templates or macros to get it done with less effort. Like:
template <typename ClassTestTag>
struct ClassTestParams
{
static std::string filename;
};
template<typename ClassTestTag>
class TheClassTest : public TheClassTestBase {
protected:
TheClassTest() : TheClassTestBase (ClassTestParams<ClassTestTag>::filename) {}
};
Then - for every set of parameters - do that:
class FooTxtTag {};
template <> std::string ClassTestParams<FooTxtTag>::value = "foo.txt";
using TheClassTestForFooTxt = TheClassTest<FooTxtTag>;
TEST_F(TheClassTestForFooTxt, xxxx) {}
However - in your specific case - I would also try GoogleTest:type-parameterized-tests.
Solution 3
Another great way to deal with this is to just extend your fixture and in the extended class supply a new default constructor which calls through to the old one with the arguments you require. For example:
struct MySpecializedTestFixture : public GenericTestFixture
{
MySpecializedTestFixture() : GenericTestFixture("a thing", "another thing") {}
};
TEST_F(MySpecializedTestFixture, FancyTest)
{
// Use the thing environment and make some assertions.
}
Gregor
I'm doing software, math, and engineering related stuff.
Updated on December 22, 2021Comments
-
Gregor over 2 years
With Google test I want to specify a Test fixture for use in different test cases. The fixture shall allocate and deallocate objects of the class
TheClass
and its data management classTheClassData
, where the data management class requires the name of a datafile.
For the different tests, the file name should vary.I defined the following Fixture:
class TheClassTest : public ::testing::Test { protected: TheClassTest(std::string filename) : datafile(filename) {} virtual ~TheClassTest() {} virtual void SetUp() { data = new TheClassData(datafile); tc = new TheClass(data); } virtual void TearDown() { delete tc; delete data; } std::string datafile; TheClassData* data; TheClass* tc; };
Now, different tests should use the fixture with different file names. Imagine this as setting up a test environment.
The question: How can I specify the filename from a test, i.e. how to call a non-default constructor of a fixture?
I found things like
::testing::TestWithParam<T>
andTEST_P
, which doesn't help, as I don't want to run one test with different values, but different tests with one fixture.