Unit Test for Callback using GTest - c++

This is the Class design for Device Discovery Library in the network using Bonjour.I need to develop Test case for it using GTest.I am new to GTEst.
Client Program need to implement IDeviceEnumerationCallback to receive Device Information
Callback will be called after Interval time and frequency
Say Interval is 200 ms and frequency is 2. it will call the two times callback after 200 ms.
class IDeviceEnumerationCallback
{
public:
/* This callback is called when Device are Enumerated and is regsitered in EnumerateWiFiDevice method */
virtual void onDeviceDiscovered( DeviceInfo* pDeviceInfo,unsigned short nNoOfDevice,void* pContext) = 0;
};
IDeviceDiscovery
{
virtual int InitialiseDeviceDiscovery(IDeviceEnumerationCallback*) = 0;
virtual void UnInitialiseDeviceDiscovery() = 0;
virtual int EnumerateDevice() = 0;
virtual void SetDiscoveryInterval(unsigned long nDiscoveryInterval);
virtual void SetDiscoveryFrequency(unsigned short nFrequency);
virtual unsigned long GettDiscoveryInterval();
virtual unsigned short GettDiscoveryFrequency();
}
class CDeviceDiscovery : public IDeviceDiscovery
{
// implemenation
}
When I Develop Unit Test for EnumerateDevice() It will return immediately Saying -1 or 1.But the result will be returned in the callback.How to Know Whether Device is enumerated properly or not using GTest.
Do I require GTest Mock Here??

You could use Gmock for this. A good explanation can be found on this page:
http://code.google.com/p/googlemock/wiki/ForDummies
You would mock IDeviceEnumerationCallback
#include <gmock/gmock.h>
class MockIDeviceEnumerationCallback : public IDeviceEnumerationCallback
{
public:
MOCK_METHOD3(onDeviceDiscovered, void(DeviceInfo* pDeviceInfo,unsigned short nNoOfDevice,void* pContext));
};
and expect an call to the function using
MockIDeviceEnumerationCallback mock;
EXPECT_CALL(mock, onDeviceDiscovered(_, _, _))
.WillOnce(Return(1));

Related

How to set expectation on a mocked method which is called inside another mocked method C++

I am a beginner with google testing framework and have looked up for the solution to this question on SO, but could not find any solutions with respect to C++. Anyway here is what i am trying to do. I have a state machine(service) which is called inside a client code.
//IStateMachine.h
class IStateMachine
{
public:
bool Run(const std::string& action) = 0;
bool IsTxnValid(const std::string& action)= 0;
}
//StateMachine.h
class StateMachine : public IStateMachine
{
bool Run(const std::string& action) override;
bool IsTxnValid(const std::string& action) override;
}
//StateMachine.cpp
bool StateMachine::IsTxnValid(const std::string& action)
{
//Checks whether the given action is valid for the given state.
}
bool StateMachine::Run(const std::string& action)
{
if(IsTxnValid(action)) // #E
{
//Do processing
return true;
}
return false;
}
//Client.h contains a class Client which has function called RunService.
Client
{
public:
void RunService();
std::unique_ptr<IStateMachine> service_; // Initialised to a non null value in either ctr or
// factory.
}
//Client.cpp
bool Client::RunService(std::string&action)
{
if(!service_->Run(action)) //Run in turn calls IsTxnValid().
{
return false;
}
return true;
}
Now i am writing a test case to test the functioning of RunService. I am expecting that if Client::IsTxnValid(param) returns false, then so should RunService.
I have successfully set up the testing recipe and could get the basic tests running. Here is the relevant test i have written. On running this test the i get the error, that IsTransitionValid is never called.
TEST_F(ClientTest, RunService)
{
EXPECT_CALL(*p_service, Run("some_action")); // #A
// EXPECT_CALL(*p_service, Run(testing::_)).WillOnce(::testing::Return(true)); //#B
EXPECT_CALL(*p_service,IsTransitionValid(testing::_)).WillOnce(::testing::Return(false)); //#C : This never gets called.
EXPECT_EQ(false, x_client->RunService());
}
How do i correctly call IsTransitionValid ?
You don't need to set this expectation. I'd go even further: you should not even depend on the implementation of Run in IStateMachine: you should only care about what input it is provided with (parameters, checked with matchers) and what output it can return (so basically only the contract between these two classes) and that's the beauty of it!
It is an implementation detail of StateMachine class (the real implementation) what is done when Run is called. The only thing you need to check in your test is to act upon the result of Run. Using triple A rule (arrange, act, assert): you arrange the test case conditions (using EXPECT_CALLs), then you act (calling RunService) and then you assert (checking the result of RunService).
The technical details:
When you create a mock by inheriting from class Foo:
class Foo {
public:
virtual ~Foo() = default;
virtual void bar() = 0;
}
By defining:
class FooMock : public Foo {
MOCK_METHOD0( bar, void());
}
gmock will add bar (the method to override) and gmock_bar (internal detail of gmock) methods to FooMock class. bar has empty implementation in this case. FooImpl and FooMock share the interface, but have different implementations - hence no call to IsTxnValid is made in Run: the mock class just doesn't know (nor care) how Run is implemented in StateMachine. Remember: in your testcase you interact with StateMachineMock and you only care about the interaction with its public interface, the contract between these two classes and how they cooperate together.
That being said, you of course need to utest the StateMachine class. It may depend on yet another interfaces in its implementations: that will be tested with different set of mocks. But Client should not know about this.

How to write a test case for module dependent function using EXPECT_CALL in Google test?

I am new to google test environment. I have a sample code written in C and want to perform unit test with Google test framework.
Below is the sample code
// My module function (test.c)
void Update_user_value(void)
{
int user_value;
user_value = get_val_module(); /* return a integer value*/
if(user_value == 0x1)
update_user_flag(true);
else
update_user_flag(false);
}
// This function is in the other module(stub.c) , so we can use Mock function
void update_user_flag(bool val)
{
struct *temp;
if(val == true)
{
temp->userflag = 1;
}
else
{
temp->userflag = 0;
}
}
I wan to write a test case for the Update_user_value function (only for test.c). Through this function, i am sending some flag value to other module (update_user_flag) to set the flag.
I have written a simple google test like this
TEST_F(sampletest, setuser_flag_true_testcase)
{
//Get value from module
ON_CALL(*ptr1, get_val_module()).WillByDefault(Return(0x1)); //Mock function
EXPECT_CALL(*ptr2, get_val_module(_)).Times(1); // Mock function
Update_user_value();
}
TEST_F(sampletest, setuser_flag_false_testcase)
{
//Get value from module
ON_CALL(*ptr1, get_val_module()).WillByDefault(Return(0x0)); //Mock function
EXPECT_CALL(*ptr2, get_val_module(_)).Times(1); // Mock function
Update_user_value();
}
My question: Is this test case is enough to validate the Update_user_value function ?
Also i want to know, EXPECT_CALL() is good to use for setting a value to other module ?
If my understanding is wrong, please suggest me a better test case ?
ON_CALL, EXPECT_CALL are macros designed to be used on mock objects. Usually the use case is as follows:
You create an interface to derive from (it will be mocked in your test).
You pass the mock object (to method or via dependency injection).
You make expectations on this object.
See example:
class Foo {
public:
virtual ~Foo() = default;
virtual int bar() = 0;
};
class FooMock : public Foo {
public:
MOCK_METHOD0(bar, int());
};
bool check_bar_over_42(Foo& foo) {
if (foo.bar() > 42) {
return true;
}
return false;
}
TEST(check_bar_over_42_test, bar_below_42) {
FooMock fooMock{};
EXPECT_CALL(fooMock, bar()).WillOnce(testing::Return(41));
ASSERT_FALSE(check_bar_over_42(fooMock));
}
TEST(check_bar_over_42_test, bar_above_42) {
FooMock fooMock{};
EXPECT_CALL(fooMock, bar()).WillOnce(testing::Return(43));
ASSERT_TRUE(check_bar_over_42(fooMock));
}
AFAIK there is no way of using EXPECT_CALLs on C-like functions. One approach for your problem would be link-time mocking: given a method get_val_module is defined in a separate library, you can create test-only library with get_val_module that will allow you to return the expected values. In tests you would link against test lib, in production - against the real lib.

Mocking an 3rd party library using fakeit

I am writing my own library/class that makes use of a 3rd party library. I want to write tests for my own class, and mock the 3rd party library. In one of the tests, I want to make sure that when a function on my class is being called, another function in the 3rd party library is also begin called as well. I though the FakeIt library would be a good idea to test this.
This is a sample of my testing code:
#include "MyTest.h"
#include "fakeit.hpp"
using namespace fakeit;
int main() {
MyTest dt;
Mock<ExternLib> mock;
Fake(Method(mock, someFunc));
ExternLib& el = mock.get();
dt.begin();
Verify(Method(mock, someFunc));
return 0;
}
When this is run though, it throws a fakeit::SequenceVerificationException with
Expected pattern: mock.someFunc( Any arguments )
Expected matches: at least 1
Actual matches : 0
Actual sequence : total of 0 actual invocations.
So clearly, the mock didn't work and it's method wasn't called. Any idea how I can mock this class and verify that its method is being called?
MyTest.cpp just is just a simple test and will be my full library/class:
#include "MyTest.h"
MyTest::MyTest() {
_manager = new ExternLib();
}
void MyTest::begin() {
result = _manager->someFunc();
}
and it's header file:
#pragma once
#include "Externlib.h"
class MyTest {
public:
MyTest();
virtual void begin();
int result = 3;
private:
ExternLib *_manager;
};
ExternLib is a mock version of the 3rd party library. My implementation implements the bare necessities of the real interface, and the functions don't actually do anything. The implementation is actually basically just there to satisfy the #include Externlib.h statements.
This is my Externlib.cpp:
#include "Externlib.h"
ExternLib:: ExternLib() {}
int ExternLib::someFunc() {
return 5;
}
and the header file:
#pragma once
class ExternLib {
public:
ExternLib();
virtual int someFunc();
};
To explain the fakeit::SequenceVerificationException:
With the line Mock<ExternLib> mock; you create a new instance of ExternLib, which does never get called by MyTest (because MyTest creates it's own instance of ExternLib).
To test invokation, you could either
expose the ExternLib instance stored in _manager to your test by making it public or add an accessor, and then spy on it (Mock<ExternLib> mock(MyTest._manager); or similar)
swap the ExternLib instance stored in MyTest::_manager with your ExternLib Mock instance.
But this means exposing your Subject Under Test's inner workings for the sake of being testable, which may not be desired.
I have never used fake it before however, it might be working when you pass mock.get() to MyTest after you make MyTest injectable.
class MyTest {
public:
MyTest(ExternaLib* lib) : _manager(lib) {}
}

How to avoid dupilcation of tests if I have an abstract class

Let’s say I’m writing a car class. It should have the methods configEngine and currentGasolineConsumption beside some other methods. So I refactored out the calculation of the gasoline consumption into an Engine class and use polymorphism to get the current gasoline consumption:
class AbstractEngine()
{
public:
virtual int calculateGasolineConsumption()
{
//... do calculation ...
return consumption;
}
// some other (pure virtual) methodes
};
class EngineA() : public AbstractEngine
{
public:
// implementation of the pure virtual methodes
};
class EngineB() : public AbstractEngine
{
public:
// implementation of the pure virtual methodes
};
class EngineC() : public AbstractEngine
{
public:
// implementation of the pure virtual methodes
int calculateGasolineConsumption() override
{
//... do new calculation ...
return consumption;
}
};
enum EngineType {
ENGINE_A,
ENGINE_B,
ENGINE_C,
};
void configEngine(EngineType engineType)
{
m_engine = m_engineFactory.create(engineType);
}
int currentGasolineConsumption()
{
return m_engine.calculateGasolineConsumption();
}
Now my question is how to unittest this without getting duplication in my unit tests?
If I write three unittests, for configEngine(ENGINE_A) and configEngine(ENGINE_B) would test basically the same code of the abstract superclass and I don’t like that duplication.
struct EngineSpec {
EngineType engineType;
int expectedValue;
};
INSTANTIATE_TEST_CASE_P(, tst_car, ::testing::Values(
EngineSpec { ENGINE_A, 3 },
EngineSpec { ENGINE_B, 3 },
EngineSpec { ENGINE_C, 7 }
));
TEST_F(tst_car,
currentGasolineConsumption_configWithEngine_expectedBehaviour)
{
EngineSpec engineSpec = GetParam();
//Arrange
m_car.configEngine(engineSpec.engineType);
//Act
auto result = m_car.currentGasolineConsumption();
//Assert
EXPECT_EQ(engineSpec.expectedValue, result);
}
Of course there is only one duplicate/unnecessary unittest but this is only a minimal example. In my real code the number of unit test duplication would explode.
One additional thing: I don’t want to move the Engine class outside of the ‘module’ and use dependency injection because I think this ‘internal Engine class’ approach is easier to handle for the client. So the client has only one interface and some enums to use this module. I would like to treat the Engine class as implementation detail.
Ideally tests should know as little about the implementation as possible, because 10 years down the line when the abstraction doesn't quite work any more, or is part of a large complicated inheritance chain (e.g. what happens when you get a hybrid engine?) the tests that appear to be a lot of effort right now will still work perfectly.
However, if you want to be pragmatic and don't mind coupling your tests to the implementation a little, you could extract a testGasolineConsumption(AbstractEngine engine) method that is called from a test case for each child. This would check that the implementation works correctly and that the base class behaviour hasn't been overridden.

Mocking class to test its methods

I want to test makeTvSeries() method without extracting getNumberOfShows, printMsg to other class and then mocking it so I thougth about mocking TvChannel class.
Is it possible to call base class method (makeTvSeries) which will call child methods: getNumberOfShows, printMsg without getting rid of virtuality? So I could use same mock class definiton in other tests for instance foo.playTvSeries(mockTvChannel) and expect calls to makeTvSeries?.
Moreover is it good practice what I am doing at all? In whole program there are also other classes which use cin and cout and as I said at the begining I didn't wanted to extract all of them to one class responsible for input/output. What are Yours experiences and what I should do ?
class MockTvChannel : public TvChannel{
public:
MOCK_METHOD0(getNumberOfShows, int());
//MOCK_METHOD0(makeTvSeries, void());
MOCK_METHOD0(printMsg, void());
};
TEST(sample_test_case, sample_test)
{
MockTvChannel channel;
EXPECT_CALL(channel, getNumberOfShows())
.Times(1)
.WillOnce(::testing::Return(10));
EXPECT_CALL(channel, printMsg())
.Times(10);
channel.makeTvSeries();
}
class TvChannel
{
protected:
virtual int getNumberOfShows(){
int nShows;
std::cin >> nShows;
return nShows;
}
virtual void printMsg(){
std::cout << "What a show!" << std::endl;
}
public:
/*virtual*/ void makeTvSeries()
{
int nShows = getNumberOfShows();
for(int i = 0; i<nShows; ++i){
printMsg();
}
}
virtual ~TvChannel() {};
};
So I could use same mock class definiton in other tests for instance foo.playTvSeries(mockTvChannel) and expect calls to makeTvSeries?
Yes, you can. And your implementation is fine.
is it good practice what I am doing at all?
It is. Following the SOLID principle, you applied next principles :
LSP : in unit test you switched real implementation and tested using mock, so your makeTvSerier works
ISP : your class has an interface
DIP : I guess, you want to use inversion of control when you pass instance of mock to other objects