TestFixtureSetUp-like method in CppUnit - c++

In NUnit, the TestFixtureSetup attribute can be used to mark a method which should be executed once before any tests in the fixture.
Is there an analogous concept in CppUnit?
If not, is there a C++ unit testing framework that supports this concept?
Based on the answer below, here is an example which accomplishes this (following the advice of the answers to this question):
// Only one instance of this class is created.
class ExpensiveObjectCreator
{
public:
const ExpensiveObject& get_expensive_object() const
{
return expensive;
}
private:
ExpensiveObject expensive;
};
class TestFoo: public CppUnit::TestFixture
{
CPPUNIT_TEST_SUITE(TestFoo);
CPPUNIT_TEST(FooShouldDoBar);
CPPUNIT_TEST(FooShouldDoFoo);
CPPUNIT_TEST_SUITE_END();
public:
TestFoo()
{
// This is called once for each test
}
void setUp()
{
// This is called once for each test
}
void FooShouldDoBar()
{
ExpensiveObject expensive = get_expensive_object();
}
void FooShouldDoFoo()
{
ExpensiveObject expensive = get_expensive_object();
}
private:
const ExpensiveObject& get_expensive_object()
{
static ExpensiveObjectCreator expensive_object_creator;
return expensive_object_creator.get_expensive_object();
}
};

Since you cannot use the fixture constructor this implies that CPPUnit is using instance per test. I think you''ll have to have a method and a static boolean flag that is read many times and written only the first time. Then call this in the constructor.

Related

gmock: force mocking out of a class method without defining and referencing a mock class?

the normal pattern of gmock testing is
class MyMockClass : public MyRealClass {
/// swap out behavior of an existng method
MOCK_method(some_method .....);
}
TEST() {
MyMockClass mock;
EXPECT_CALLED(mock.some_method);
/// ******* here I have to explicitly pass in the mock obj into the system
MyConsumerClass myconsumer(mock);
myconsumer.do_something_to_trigger_mock__some_method();
}
in the above "****" line I have to explicitly pass in a mock obj into the system, i.e. compose my consumer obj with a mock obj. But now I face an existing consumer class impl, its constructor does not allow passing in the dependency objects; in fact I can probably argue that it's impossible to list all the dependency objects in the ctor of a consumer class; more importantly, my real case is that the consumer class to be tested sits several levels above the mock obj:
class MyConsumerClass {
private:
MyHelperClass helper
public:
void trigger() {
helper.trigger_again();
}
}
class MyHelperClass {
BottomClass bottom;
public:
void trigger_again() {
bottom.do_something();
}
}
class BottomClass {
public :
void do_something();
}
in this case, in our unit test, we can only instantiate the top level MyConsumerClass, and I was hoping to verify that when I call myconsumer.trigger(), I could verify that the BottomClass.do_something() is called, possibly also verifying that it's called with a specific argument. But the above class hierarchy is written so that I can not pass in a mock BottomClass obj from the top level.
in jmock or jmockit, I remember it's possible to globally wipe out the behavior of BottomClass.do_something(), without referring to a specific mock obj, i.e. "static mocking", as they are called in jmockit. is it possible to do something like that in gmock (c++)? thanks
Converting the comment to an answer:
I can think of two things:
Why don't you test your classes separately? For example, write a separate test for MyHelperClass.
If dependency injection doesn't work for you, GMock allows you to do static mocking by templatizing your classes: Convert your classes to templates, then instantiate the template with real classes for production and with mock classes for testing. See here for an example.
In your case, your code could be rewritten to something like this:
//-----------------------------------------------------------------------------
// Real classes used in production
//-----------------------------------------------------------------------------
class BottomClass {
public:
void do_something();
};
//-----------------------------------------------------------------------------
// Templatized classes used in test or production
//-----------------------------------------------------------------------------
template <class BType>
class MyHelperClass {
public:
BType bottom;
public:
void trigger_again() { bottom.do_something(); }
};
template <class BType, template <typename> class HType>
class MyConsumerClass {
public:
HType<BType> helper;
public:
void trigger() { helper.trigger_again(); }
};
//-----------------------------------------------------------------------------
// Mocked classes used in test
//-----------------------------------------------------------------------------
class MockedBottomClass {
public:
MOCK_METHOD(void, do_something, (), ());
};
TEST(BottomClassTest, Test1) {
MyConsumerClass<MockedBottomClass, MyHelperClass> mock;
EXPECT_CALL(mock.helper.bottom, do_something());
mock.trigger();
}
I had to convert some of your private members to public members for the test to work.
Live example here: https://godbolt.org/z/qc3chdxKz

C++ Overwrite initializer list in unit test

I have some C++ code like this that I want to unit test:
class Example
{
private:
ExpensiveObject expensiveObject;
public:
Example() : expensiveObject() {
... constructor code
}
methodA() {
... some code
}
}
To write a unit test for methodA I need to create an instance of Example. The problem is that I don't want to initialize expensiveObject, I would want to set it to null in my unit test (I am using Google Test). Is there a way to do it?
expensiveObject cannot be assigned null. What you might want is to have a smart pointer to ExpensiveObject, and have multiple constructors or better you want to inject your dependencies.
class Example
{
private:
std::shared_ptr<ExpensiveObject> expensiveObject;
public:
Example(std::shared_ptr<ExpensiveObject> ptr) : expensiveObject(ptr) {
//... constructor code
}
methodA() {
//... some code
}
}
Now you can test it for null scenarios as well
Example ex{nullptr};
ex.methodA();
I can't think of any way to do this without slightly modifying the definition of the Example class. However, if you can tolerate to do this, there are several ways to do this: dependency injection using pointers as the other answer mentioned, or templatizing the class as shown below:
// Used for production.
class ExpensiveObject {
// Expensive stuff here
};
// Only used for testing.
class CheapObject {
// Cheap stuff here
};
// Instantiate with ExpensiveObject for production and with CheapObject for
// testing.
template <class T>
class Example {
private:
T expensiveObject;
public:
Example() : expensiveObject() {}
int methodA() { return 1; }
};
TEST(Example, Test1) {
// CheapObject is used for testing.
Example<CheapObject> example;
EXPECT_EQ(example.methodA(), 1);
}
Live example: https://godbolt.org/z/7e1rhWY4b

Google Mock a Singleton C++ Class

I am having difficulties in figuring out how to mock the singleton class, and test it in another class. The goal is to verify that a method from a singleton class (Alarm) gets called from another class (CEvnts).
I was able to test this successfully by eliminating the singleton function, but since it is legacy code, I cannot change the structure.
Going through several articles and posts online, I have not found a clear answer. Does anyone know how to set up the Google Test for a singleton class? Any references or articles can be a big help.
Singleton Class:
class Alarm
{
public:
Alarm();
virtual ~Alarm();
// Singleton
static Alarm* find(void)
{
if (!Alarm_Instance)
{
Alarm_Instance = new Alarm();
}
return Alarm_Instance;
}
// Member methods
virtual ENUM_TYPE getType(ENUM_TYPE ENUM_ARG);
private:
static Alarm* Alarm_Instance;
};
ENUM_TYPE Alarm::getType(ENUM_TYPE ENUM_ARG)
{
return aMatch[ENUM_ARG].aType;
}
Mock:
class Alarm_Mock : public Alarm
{
public:
Alarm_Mock();
virtual ~Alarm_Mock();
MOCK_METHOD1(getType, ENUM_TYPE(ENUM_TYPE ENUMONE));
};
Google Test:
class Ev_test: public testing::Test
{
void SetUp()
{
mpsEV= new CEvents();
ON_CALL(msMock, getType(_)).WillByDefault(Return(SOME_ENUM));
}
void TearDown()
{
delete mpsEV;
}
protected:
Alarm_Mock msMock;
CEvents* mpsEV;
};
TEST_F(Ev_test, testGetFunctions)
{
EXPECT_CALL(msMock, getAlarmType(_))
.Times(1);
mpsEV->aMethod(arg1, arg2, arg3, arg4);
}
Class Method to Test - Does getType from Class Alarm get called?:
void CEvents::aMethod(arg1, arg2, arg3, arg4)
{
Alarm::find()->getType(arg1);
}
CEvents::aMethod() invokes getType(arg1) on the instance returned by Alarm::find(), which will be different from your mock object.
A quick fix would be to move the assignment of Alarm::Alarm_Instance out of Alarm::find() and into Alarm::Alarm().

C++ - Creating a Spy in unit tests

I have some C++ code as follows:
class MyClass
{
public:
MyClass(OtherClass *obj)
{
obj_ = obj;
}
void myMethod()
{
// Do something
int value = obj_->otherMethod();
// Do something else
}
private:
OtherClass *obj_;
}
I want to create a unit test to test the functionality of myMethod(). Unfortunately, OtherClass is an external library and its methods are not declared virtual (so I can't inherit the methods and stub them out in a mock). I have some experience with Mockito where I might have used a spy for this purpose. But I can't seem to find an equivalent in C++.
I'm using the googletest framework for now and the context for this question (if it helps) is in ROS, where I'm actually trying to stub out tf::TransformListener.
Question 1: Is there an alternative to spies that I might not know of and can leverage in this situation?
Question 2: If there isn't, is there a quick-and-easy way for me to restructure my code so that I can leverage a mock?
Solved by doing the following:
class IOtherMethodAdapter
{
public:
virtual int otherMethod() = 0;
}
class OtherClassOtherMethodAdapter : public IOtherMethodAdapter
{
public:
int otherMethod() { return obj_->otherMethod(); }
private:
OtherClass *obj_;
}
Now I use a pointer to IOtherMethodAdapter in MyClass instead of OtherClass and for testing I simply initialize the implementation of the interface to a stubbed/mock object. If there is another way, feel free to post that solution too.

Specify constructor arguments for a Google test Fixture

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 class TheClassData, 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> and TEST_P, which doesn't help, as I don't want to run one test with different values, but different tests with one fixture.
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.
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.
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.
}
If you overload the SetUp method as suggested here, and you want to ensure that you remember to use the overloaded SetUp, you can use an assertion in the TearDown method.
class my_fixture : public ::testing::Test
{
protected:
bool SETUP_HIT_FLAG = false;
void SetUp(double parameter)
{
...
SETUP_HIT_FLAG = true;
}
void TearDown() override
{
assert(SETUP_HIT_FLAG && "You forgot to call SetUp with your parameter!");
}
};
Another way using templates:
template<int N>
class Fixture : public ::testing::Test { ... }
using FixtureForTest = Fixture<1000>;
TEST_F(FixtureForTest, test) { ... }
For this specific case, I feel it is much easier to get rid of the test fixture altogether. The SetUp function can instead be replaced with a helper function that instantiates the class with the required file name. This permits the use of TEST instead of TEST_P or TEST_F. Now each test case is a standalone test which creates its own test class instances with the helper function or directly in the body of the test case.
For example:
using namespace testing;
TEST(FooClassTest, testCase1)
{
FooClass fooInstance("File_name_for_testCase1.txt");
/* The test case body*/
delete fooInstance;
}