How to test method in google test, using std::function? - c++

I would like to test method "methodToTest" in class A:
typedef std::function F_global;
struct A
{
F_global m_F_global;
A(F_global m_F_global) : p_F_global(m_F_global) {}
void methodToTest()
{
m_F_global(5);
}
};
I have got a mock class:
class RunMock
{
public:
MOCK_METHOD1(run, void (int));
};
Below I have got a test case:
class TestClass : public testing::Test
{
protected:
void SetUp();
std::unique_ptr<A> m_aa;
std::unique_ptr<RunMock> m_runMock;
};
void UecSimplePortTestSuite::SetUp()
{
m_aa = make_unique<A>(m_runMock->run);//IT DOESN'T WORK I DON'T KNOW HOW TO FORWARD A METHOD run from RunMock to constructor
}
TEST_F(UecSimplePortTestSuite, testForwardMessage)
{
EXPECT_CALL(*m_runMock, run(_));
m_aa->methodToTest();
}
Generally I don't know how transfer a method "run" from Mock class "RunMock" in "UecSimplePortTestSuite::SetUp()". I would like to do this, because
I would like to "EXPECT_CALL(*m_runMock, run(_));" in UecSimplePortTestSuite.testForwardMessage to test "methodToTest()".
I think that good idea could be to use lmbda, std::boost::bind or something like this.

You can pass a lambda to the constructor of A in the SetUp() :
m_runMock.reset( new RunMock );
m_aa.reset( new A( [&](int value){ m_runMock->run(value); } );
This :
m_runMock->run
is not going to do what you thing, and it is a compilation error. You can read this parashift QA and here how to use pointer to member function.

Related

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 with templates and inheritance

I am currently trying to get templates and inheritance to behave nicely with GMock. I have a feeling what I am trying to do are two opposing ideologies and I should just use an interface, but I wanted to avoid using an interface due to possible virtual call overheads (perhaps I am optimizing prematurely)
Anyway, here's an example of what I am trying to do
class ConcreteObj {
public:
// Called a lot and so don't want to hit possible virtual overhead
void performant_function();
};
class MockObj {
public:
MOCK_METHOD(void, performant_function, (), ());
};
class ITest {
public:
template<typename T>
void test_function(T& );
};
class ConcreteTest : public ITest {
public:
template<typename T>
void test_function(T& ) {};
template<>
void test_function<ConcreteObj>(ConcreteObj& obj) {
// Do something with concrete object
obj.performant_function();
}
template<>
void test_function<MockObj>(MockObj& obj) {
// Do something with mock object
}
}
What I would then like to do, is something like the following
ConcreteTest concrete_test;
ITest* test = &concrete_test;
// In production
ConcreteObj concrete_obj;
test.test_function(concrete_obj);
// In test
MockObj mock_obj;
test.test_function(mock_obj);
Which would then call ConcreteTest via the ITest interface, but the above would clearly not work without some sort of cast to the ConcreteTest as you can't have a virtual templated function.
I would be grateful if anyone has any ideas on how I could do the following, although I will probably resign myself to using a pure virtual interface and deal with the possible vtable overhead that would come if there was a IObj interface that ConcreteObj and MockObj inherited from.
To avoid runtime polymorphism, you can use template, as follow:
class ConcreteObj {
public:
// Called a lot and so don't want to hit possible virtual overhead
void performant_function();
};
class MockObj {
public:
MOCK_METHOD(void, performant_function, (), ());
};
class ITest {
public:
virtual ~ITest() = default;
virtual void test_function() = 0;
};
template <typename T>
// requires (T t){ t.performant_function(); } // C++20
class ConcreteTest : public ITest {
T t;
public:
explicit ConcreteTest(T& t) : t(t) {}
void test_function()
{
for (int i = 0; i != big_number; ++i) {
t.performant_function();
}
// ...
}
};
and then
// In production
ConcreteObj concrete_obj;
ConcreteTest<ConcreteObj> concrete_test{concrete_obj};
ITest* test = &concrete_test;
test->test_function();
// In test
MockObj mock_obj;
// EXPECT_CALL(..)
ConcreteTest<MockObj > concrete_test{mock_obj};
ITest* test = &concrete_test;
test->test_function();
If you think about the requirements you are specifying for ConcreteObj, you are asking for two things:
Absolute minimal per-call overhead of the performant_function() method.
Be able to swap-in different implementations depending on the context (i.e. when running tests vs production).
There is only one guaranteed way to get both at the same time: templates.
Your posted code doesn't provide a lot of context, so odds are that it's not going to be that simple, but it would look at lot like this:
class ConcreteTest : public ITest {
public:
template<typename T>
void test_function(T& obj) {
// Do something with obj
obj.performant_function();
};
};
// ...
ConcreteTest concrete_test;
ITest* test = &concrete_test;
// In production
ConcreteObj concrete_obj;
test->test_function(concrete_obj);
// In test
MockObj mock_obj;
test->test_function(mock_obj);
However, you ask:
(perhaps I am optimizing prematurely)
And the answer is pretty much yes. Compilers are really good at optimizing stuff. In your scenario, you could compile with -flto and use:
class IObj {
public:
virtual void performant_function() = 0;
};
class ConcreteObj final : public IObj {
public:
virtual void performant_function() = 0;
};
and that would have a solid chance of getting rid of the overhead during an optimization pass called devirtualization.

Using dependency injection and mocking it with gmock

I have implemented a Dependency Injection pattern in my code. I did that to be able to mock a service using gmock. The DI implementation works in production code, however, I am having trouble with my test setup. When using the EXPECT_CALL macro, I get "expression must have class type" error. I believe this is related to the way I designed the dependency, but I can't find an alternative solution (lack of experience). I have browsed previous threads on similar issues, but none helped. Would you be kind to take a look at the code below and hint possible workarounds (simplified code example using a Car-Engine interface)?
// Engine interface class with pure virtual functions
class IEngine
{
public:
virtual ~IEngine() = default;
virtual void start() = 0;
virtual void stop() = 0;
};
// A V8Engine class implementing this interface
class V8Engine : public IEngine
{
public:
void start() override { std::cout << "V8 Engine started\n"; };
void stop() override { std::cout << "V8 Engine stopped\n"; };
};
// Car.h file
class Car
{
public:
Car(IEngine *engineService);
void Drive();
private:
IEngine* mEngine = nullptr;
};
// Car.cpp file
Car::Car(IEngine* engineService)
: mEngine(engineService)
{
if (mEngine == nullptr)
{
throw std::invalid_argument("service must not be null");
}
}
void Car::Drive()
{
mEngine->start();
mEngine->stop();
}
I would like to be able to mock the engine implementation and instead of using a "real V8Engine", utilize the mock. Here is how I set up my test:
class MockEngine : public IEngine
{
public:
MOCK_METHOD(void, start, (), (override));
MOCK_METHOD(void, stop, (), (override));
};
TEST(TestCarClass, TestCarWithMockEngine)
{
IEngine *mockEngine = new MockEngine;
Car carUnderTest(mockEngine);
carUnderTest.Drive();
EXPECT_CALL(mockEngine, start()); // This is the part where I get the error due to invalid mockEngine setup
}
EXPECT_CALL expects mock object as first parameter, you pass reference to mock.
either use *mockEngine:
TEST(TestCarClass, TestCarWithMockEngine)
{
IEngine *mockEngine = new MockEngine;
Car carUnderTest(mockEngine);
EXPECT_CALL(*mockEngine, start());
carUnderTest.Drive();
}
or avoid allocation directly:
TEST(TestCarClass, TestCarWithMockEngine)
{
MockEngine mockEngine;
Car carUnderTest(&mockEngine);
EXPECT_CALL(mockEngine, start());
carUnderTest.Drive();
}

Pass function as parameter to parent method from derived class

I have the following code, where the execute() method accepts a function as a parameter and executes it. The start() method then calls execute() in order to run method1().
class Test
{
int Test::start(void)
{
execute(&Test::method1);
return 1;
}
void Test::execute(void(Test::*func)(void))
{
(this->*func)();
}
void Test::method1(void)
{
//Do something...
}
}
Now I want to modify this so I achieve the following:
Create a base class called TestRunner and and move the execute() method to it
Have Test inherit from TestRunner, where it can call the execute() method to run its local methods
I am trying the following, but got stuck in how I should specify the method parameter in execute() i.e. what right now I have as TestRunner::*func.
class TestRunner
{
public:
TestRunner()
{
//Do something...
}
protected:
void execute(void(TestRunner::*func)(void))
{
(this->*func)();
}
}
class Test : TestRunner
{
public:
Test() : TestRunner()
{
}
int start()
{
TestRunner::execute(&Test::method1);
return 1;
}
private:
void method1(void)
{
//Do something
}
}
If I compile the code like it is I obviously get these errors:
no matching function for call to 'Test::execute(void (Test::*)())'
and
no known conversion for argument 1 from 'void (Test::)()' to 'void
(TestRunner::)()'
Can anyone guide me in the right direction here or do I need to do something completely different to achieve what I want?
I've used this answer here to come up with a solution: C++ Pointers to Member Functions Inheritance
Create a callback class:
class Callback
{
public:
virtual ~Callback() { }
virtual void doSomething()=0;
};
Extend the callback class to define how a function is executed and use a template:
template<class T>
class BCallback: Callback
{
public:
~BCallback() { }
BCallback(T *obj, void(T::*fn)()): obj_(obj), fn_(fn) { };
void doSomething()
{
(obj_->*fn_)();
}
private:
T *obj_;
void(T::*fn_)();
};
Use a callback object in the base class:
class TestRunner
{
protected:
void execute(Callback *cb)
{
cb->doSomething();
}
};
Run the method from the derived class:
class Test: TestRunner
{
public:
int start()
{
BCallback<Test> cb(this, &Test::method1);
this->execute(&cb);
return 1;
}
private:
void method1(void)
{
//Do something
}
};
You can use a typedef like this:
typedef void(Test::*Callback)(void);
You can then make your executing function take objects of type Callback. It will look like this Test::execute(Callback).
When calling it, use static_cast<>:
Test tester;
tester.execute(static_cast<Callback>(&DerivedTest::someMethod));
Example Test::execute(Callback) implementation:
Test::execute(Callback cb) {
(this->*cb)();
}
This way you can avoid writing whole two new classes (one of them a template, even!) just to do a simple thing. As a bonus, you can use function overloading to get Test::execute for different function signatures.

Writing Gameboy emulator in C++, how to test opcodes (Google Test Framework)?

I'm trying to write GameBoy emulator, but I'm not sure how should I test my CPU_LR39502 class. To avoid huge if-else-if / switch-case statements, I came up with idea to put opcode functor into map, which takes opcode as key:
class Functor
{
std::function<void()> m_function;
public:
Functor(std::function<void()>&& function)
{
m_function = std::move(function);
}
void operator()()
{
m_function();
}
};
class BaseOpcodeFunctor : public Functor
{
unsigned char m_opcode;
std::string m_disasmString;
public:
BaseOpcodeFunctor(std::function<void()>&& function,
unsigned char opcode,
std::string&& disasmString)
: Functor(std::move(function)),
m_opcode(opcode),
m_disasmString(std::move(disasmString)) {}
std::string disasm()
{
return m_disasmString;
}
unsigned char getAssignedOpcode()
{
return m_opcode;
}
};
And example of it:
class CPU_LR35902
{
...
std::map<unsigned char, BaseOpcodeFunctor> m_baseOpcodeMap;
public:
CPU_LR35902()
{
...
initializeBaseOpcodeMap();
}
...
private:
void addFunctorToBaseOpcodeMap(BaseOpcodeFunctor&& functor);
void initializeBaseOpcodeMap()
{
...
addFunctorToBaseOpcodeMap(BaseOpcodeFunctor([this]() {
bitwiseRotationLeft(REGISTER_A);
}, 0x07, "RLCA"));
}
void bitwiseRotationLeft(LR35902_8BIT_REGISTERS reg)
{
resetFlag(FLAG_Z);
resetFlag(FLAG_N);
resetFlag(FLAG_H);
setFlag(FLAG_C, registers_8bit.at(reg) >> 7);
registers_8bit.at(reg) <<= 1;
registers_8bit.at(reg) |= getFlag(FLAG_C);
}
...
};
And this somehow makes me think about two problems. I actually wanted to write implementation of opcode immediately when adding it to m_baseOpcodeMap, but to make it testable, I wrote implementation as a member function (here bitwiseRotationLeft as example) and I call it in lambda - and I'm not sure if this is correct approach.
Currently, to test some implementations, I've got something like this (using google test framework):
#include "cpu_lr35902.h"
#include <gtest/gtest.h>
class CPUTest : public ::testing::Test
{
protected:
CPU_LR35902 cpu_testable;
};
TEST_F(CPUTest, test_bitwiseRotationLeft)
{
cpu_testable.flags = 0;
cpu_testable.clearRegisters();
//0xA5 = 1010 0101, after: 0100 1011 = 0x4B
cpu_testable.registers_8bit.at(CPU_LR35902::REGISTER_A) = 0xA5;
cpu_testable.bitwiseRotationLeft(CPU_LR35902::REGISTER_A);
ASSERT_EQ(1, cpu_testable.getFlag(CPU_LR35902::FLAG_C));
ASSERT_EQ(0x4B, cpu_testable.registers_8bit.at(CPU_LR35902::REGISTER_A));
}
but to get access to private members of CPU_LR35902, I have to add
FRIEND_TEST(CPUTest, test_name);
in CPU_LR35902 class - after that I can reach private members of tested class in TEST_F, but I can't access them in CPUTest class (for SetUp / TearDown). Considering the fact, that I've got a little bit more of tests and I'm going to have a plenty of them, I think that adding FRIEND_TEST for every test makes everything somehow bad-looking. I'm in touch with C++ for some time, but I've got completely zero experience in using Google Test Framework and my intuition tells me that there must be a better way to do it. Any clues will be gladly appreciated :)
How do I test private class members without writing FRIEND_TEST()s?
Write the tests as members of the fixture class:
class Foo {
friend class FooTest;
...
};
class FooTest : public ::testing::Test {
protected:
...
void Test1() {...} // This accesses private members of class Foo.
void Test2() {...} // So does this one.
};
TEST_F(FooTest, Test1) {
Test1();
}
TEST_F(FooTest, Test2) {
Test2();
}
This makes it so you only have to friend one class per test fixture, without the need of including gtest in your header (or your project).
You can also just make a normal class that is a friend of the main class that is purely used by tests to access private members.
class Foo {
friend class FooTesting;
...
};
class FooTesting {
public:
static int read_private_variable1( Foo& );
};
TEST_F(FooTest, Test1) {
Foo bar;
EXPECT_EQ( FooTesting::read_private_variable1( bar ), 5 );
}
Probable not the answer your looking for but you could conditional make the cpu params public for testing
class CPU_LR35902
{
...
public:
...
#ifndef TESTING_CPU
private:
#endif
...
};