The pure virtual class
class ConfigGetter {
public:
virtual const std::string Get(const char *name,
const char *default_value) const = 0;
};
The mock
class MockConfigGetter : public engine::ConfigGetter {
public:
MOCK_CONST_METHOD2(Get, const std::string(const char *, const char *));
};
Test case
TEST(ConfigTest, NormalString) {
NiceMock<MockConfigGetter> getter;
EXPECT_CALL(getter, Get("SERVER_LISTEN_PORT", ""))
.WillRepeatedly(Return("80"));
// Pass
ASSERT_EQ("80", getter.Get("SERVER_LISTEN_PORT", ""));
// GetNewConfig internal call getter->Get("SERVER_LISTEN_PORT", "")
auto f = engine::GetNewConfig(&getter);
ASSERT_NE(f, nullptr);
// Failure
ASSERT_EQ(80, f->listen_port);
}
And good mock reports:
Unexpected mock function call - returning default value.
Function call: Get(0x556fb6ea4860 pointing to "SERVER_LISTEN_PORT", 0x556fb6ea4843 pointing to "")
Returns: ""
Google Mock tried the following 1 expectation, but it didn't match:
/home/phillip/projects/engine-test/src/config/config-test.cpp:26: EXPECT_CALL(getter, Get("SERVER_LISTEN_PORT", ""))...
Expected arg #0: is equal to 0x556fb6ea2878 pointing to "SERVER_LISTEN_PORT"
Actual: 0x556fb6ea4860 pointing to "SERVER_LISTEN_PORT"
Expected arg #1: is equal to 0x556fb6ea27bc pointing to ""
Actual: 0x556fb6ea4843 pointing to ""
Expected: to be called any number of times
Actual: called twice - satisfied and active
arg0 and arg1 is exactly the same as EXPECT_CALL. I don't know why the second call fail to match.
This happens because gmock compares values of arguments, i.e. pointers. To compare strings you need to add corresponding matchers, i.e.
EXPECT_CALL(getter, Get(StrEq("SERVER_LISTEN_PORT"), StrEq("")))
.WillRepeatedly(Return("80"));
Related
I created a test case with Catch2 and I am trying to use TrompeLoeil for finer testing.
However the mock calls either don't happen at all, or happen but don't seem to be detecting by the framework.
Here is a minimal reproductible example :
class MyRealClass
{
public:
virtual int returnSumOfValues(int a, int b)
{
return a + b;
}
};
class MyMockClass : public MyRealClass
{
public:
MAKE_MOCK2(returnSumOfValues, int(int,int));
};
class MyTestedClass
{
public:
MyTestedClass(MyRealClass* _computeObj)
: computeObj(_computeObj)
{
}
int compute()
{
return computeObj->returnSumOfValues(2,3);
}
MyRealClass* computeObj;
};
TEST_CASE("Testing Trompe L'oeil")
{
auto mock = new MyMockClass();
MyTestedClass testedClass(mock);
int val = testedClass.compute();
CHECK(val == 5);
REQUIRE_CALL(*mock, returnSumOfValues(2,3)).RETURN(5);
}
And here is the error I get from running this test :
------------------------------------------------------------------------------- Testing Trompe L'oeil
------------------------------------------------------------------------------- ../../../src/MEGAAutoTests/UnitTests/control/TransferBatchTests.cpp:164
...............................................................................
../../../src/MEGAAutoTests/UnitTests/main.cpp:38: FAILED: explicitly
with message: No match for call of returnSumOfValues with signature
int(int,int) with.
param _1 == 2
param _2 == 3
I debugged this step by step and the mocked returnSumOfValues() is the one being executed.
However, if I make MyRealClass::returnSumOfValues() not virtual, the mock class is not used at all.
And the error is :
------------------------------------------------------------------------------- Testing Trompe L'oeil
------------------------------------------------------------------------------- ../../../src/MEGAAutoTests/UnitTests/control/TransferBatchTests.cpp:164
...............................................................................
../../../src/MEGAAutoTests/UnitTests/main.cpp:43: FAILED: CHECK(
failure.empty() ) with expansion: false with message: failure :=
"../../../src/MEGAAutoTests/UnitTests/control/TransferBatchTests.
cpp:172 Unfulfilled expectation: Expected
*mock.returnSumOfValues(2,3) to be called once, actually never called
param _1 == 2
param _2 == 3 "
This seems to not be consistent with the official documentation, which states that :
The line MAKE_MOCK2(log, void(int severity, const std::string& msg))
creates a mock function void Logger::log(int, const std::string&). If
MAKE_MOCKn(...) or MAKE_CONST_MOCKn(...) are used to implement a
virtual function from a base class, it is always recommended to add a
third macro parameter override since it gives the compiler an ability
to complain about mistakes.
Recommended, not required. And to give the compiler more information, not to make the test work.
TL, DR
Why is my code sample not working?
Why do I need to make mocked functions virtual when the documentation suggests it is not mandatory?
The issue was that expectations need to be set beforehand.
I though they worked like assertions, checking a state after the code was executed, but this is not the case.
In this case, moving the call solved the problem. Here is the fixed code sample :
TEST_CASE("Testing Trompe L'oeil")
{
auto mock = new MyMockClass();
MyTestedClass testedClass(mock);
REQUIRE_CALL(*mock, returnSumOfValues(2,3)).RETURN(5);
int val = testedClass.compute();
CHECK(val == 5);
}
This is the solution to the first problem, the second one (only virtual functions can be mocked) remains unanswered.
So I have a class which is calling method from other class, but eventually it will return a string or so
This is my class: Person.cpp
Person::Person(){}
std::string Person::getName(void) {
return namespaceX::namespaceY::StringVal;
}
This is my mock / test class:
class MockPerson : public Person{
public:
typedef ::testing::StrictMock<Person> Strict;
MockPerson() : Person(){}
~MockPerson() override = default;
MOCK_METHOD0(getName, std::string ());
std::string callFunc(){
return Person::getName();
}
This is my test header file:
class PersonTest : public testing::Test {
public:
PersonTest () :
mock(std::make_shared<MockPerson ::Strict>()){}
~PersonTest (void) override = default;
std::shared_ptr<MockPerson ::Strict> mock;
};
This is my test:
#include "testHeader.hpp"
TEST_F(PersonTest , case1)
{
EXPECT_CALL(*mock, getName());
ASSERT_EQ(someString, mock->callFunc());
}
The test setup looks good to me however when I ran the test, it gives me:
Actual function call count doesn't match EXPECT_CALL(*mock, getName())...
Expected: to be called once
Actual: never called - unsatisfied and active
And the values return in the ASSERT statement is just the default value of the string ("").
Is there a way to go through it? I saw online that we should pass in an actual object to the function but in this case a very simple function causes more troubles than complex ones. Any help is appreciated.
First, compiling your example with g++ gives me the following error:
error: 'using element_type = class testing::StrictMock<Person>' {aka 'class testing::StrictMock<Person>'} has no member named 'gmock_getName'
This can be fixed by passing MockPerson as the template parameter for StrictMock, instead of passing Person:
typedef ::testing::StrictMock<MockPerson> Strict;
Second, your declaration of callFunc explicitly calls the getName function of the Person class. This bypasses the mocked version of getName and hence the instrumentation that Google Mock inserts to keep track of the number of function calls. Therefore, you get the assertion failure about the function call count mismatch. This can be fixed by making callFunc call the getName of the current class (MockPerson) instead:
std::string callFunc() { return getName(); }
Third, the mocked getName will return a default-constructed std::string, hence you get the "". You can change the behavior for all tests belonging to PersonTest, by adding this declaration in the PersonTest constructor:
ON_CALL(*mock, getName()).WillByDefault(Return("xyz"));
Or you can set the behavior for individual tests by modifying the EXPECT_CALL declarations to:
EXPECT_CALL(*mock, getName()).WillRepeatedly(Return("xyz"));
For both variants, the assert for your callFunc should then work as expected:
ASSERT_EQ("xyz", mock->callFunc());
I'm making a mock class of istream to test a class. But the mocked object is not passing to the actual class i want to use in.
This is the mock class.
class MockStream{
private:
std::string filename_;
public:
MockStream(){
}
MockStream(std::string filename, std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out):filename_(filename){
}
MockStream(const MockStream &a){}
MockStream& operator=(const MockStream& a){
return *this;
}
~MockStream(){}
MOCK_CONST_METHOD0(is_open,bool());
MOCK_METHOD0(close,void());
MOCK_METHOD2(read,MockStream&(char*,std::streamsize));
MOCK_METHOD2(write,MockStream&(const char*,std::streamsize));
MOCK_METHOD2(seekg,MockStream&(std::streamoff,std::ios_base::seekdir));
MOCK_METHOD1(seekg,MockStream&(std::streampos));
MOCK_METHOD0(get_filename,std::string());
};
test:
TEST(random_access_stack, mocked_test)
{
RandomAccessStack<TestClass,u_int64_t,MockStream> stack;
MockStream mocked;
EXPECT_CALL(mocked,is_open()).Times(1).WillOnce(testing::Return(true));
stack.SetStream(mocked);
EXPECT_TRUE(stack.is_open());
}
SetStream function:
void SetStream(STREAM& handle){
file_handle_ = handle;
}
where file_handle_ is of type MockStream passed by template
The output is:
GMOCK WARNING:
Uninteresting mock function call - returning default value.
Function call: is_open()
Returns: false
NOTE: You can safely ignore the above warning unless this call should not happen. Do not suppress it by blindly adding an EXPECT_CALL() if you don't mean to enforce the call. See https://github.com/google/googletest/blob/master/googlemock/docs/CookBook.md#knowing-when-to-expect for details.
/build/libs/storage/tests/gtest/random_access_stack_tests.cpp:79: Failure
Value of: stack.is_open()
Actual: false
Expected: true
/build/libs/storage/tests/gtest/random_access_stack_tests.cpp:73: Failure
Actual function call count doesn't match EXPECT_CALL(mocked, is_open())...
Expected: to be called once
Actual: never called - unsatisfied and active
I'm attempting to mock a DB interface call and return a polymorphic data type as a reference using SetArgReferee. The method I'm mocking takes 2 base class reference arguments. While setting the value for the 2nd reference argument in SetArgReferee, a derived class object is used as the value. In the source code under test, the returned 2nd reference argument is again cast to the derived class and used. This seems to be not working properly.
I have a DBInterface that I'm mocking as below.
class DBInterface {
...
public:
virtual void service(Msg& req, Msg& resp, bool flag) = 0;
...
};
class DBInterfaceMock : public DBInterface {
public:
MOCK_METHOD3(service, void(Msg& req, Msg& resp, bool flag));
};
The test mocks this service call using the EXPECT_CALL as shown below
TEST_F(SessionTest, SessionInt) {
DBInterfaceMock mockDb;
Session* session = new Session(mockDb);
// DerivedMsg inherits from Msg and contains a map
DerivedMsg derivedMsg;
// populating the map inside the derivedMsg
// ...
// ...
EXPECT_CALL(mockDb, service(_, _, false))
.Times(1)
.WillDo(SetArgReferee<1>(*(dynamic_cast<Msg*>(&derivedMsg))));
session->init();
....
....
}
On calling the session->init(), I'm expecting that the mocked service call must return the values as populated in derivedMsg. However, the code hits an ASSERT where the map size is 0 even though the value to be returned in the SetArgReferee has been populated correctly.
In the production code, once the service call executes successfully, the reference argument is retrieved by doing a dynamic_cast to the desired derived type as shown below.
service(req, resp, false);
DerivedMsg derivedResp = *(dynamic_cast<DerivedMsg*>(&resp));
uint16_t size = derivedResp.getMap().size(); //returns a 0 size.
Is there a better way of achieving this? It doesn't seem to be working this way.
I used lualite to wrap the following object in lua:
class SpriteComponent : public Component
{
public:
SpriteComponent();
std::string name() const;
std::string textureId() const;
void setTextureId(const std::string& id);
int spriteCoordX() const;
void setSpriteCoordX(int value);
int spriteCoordY() const;
void setSpriteCoordY(int value);
};
The binding code:
module(L,
class_<SpriteComponent>("SpriteComponent")
.constructor("new")
.def("name", &SpriteComponent::name)
.property("textureId",
&SpriteComponent::textureId, &SpriteComponent::setTextureId)
.property("spriteCoordX",
&SpriteComponent::spriteCoordX, &SpriteComponent::setSpriteCoordX)
.property("spriteCoordY",
&SpriteComponent::spriteCoordY, &SpriteComponent::setSpriteCoordY)
);
Is there a way (either on the lua side or the C++ side) to get a list of properties? If I list the pairs in the resulting table, I only get name and __instance.
local o = SpriteComponent.new()
for key,value in pairs(o) do
print("found member " .. key);
end
I even tried some of these table printers, but no luck.
I'm the author of lualite. I wrote the library to be minimalist and fast and did not foresee the need for reflection :) Anyway, what you are looking for can be found as 2 static members:
static ::std::unordered_map<char const*, detail::map_member_info_type,
detail::unordered_hash, detail::unordered_eq> getters_;
static ::std::unordered_map<char const*, detail::map_member_info_type,
detail::unordered_hash, detail::unordered_eq> setters_;
the char const* is the name of the property, the value being a map_member_info_type, which are essentially two pointers, one to a lualite stub, the other to the C++ member function.
struct map_member_info_type
{
lua_CFunction callback;
member_func_type func;
};
If you like, I can make both members public. The way properties work is as follows:
A default getter is (usually) set in the wrapped class's instance table:
lua_pushcclosure(L, default_getter<C>, 2);
rawsetfield(L, -2, "__index");
This points to the default getter:
template <class C>
int default_getter(lua_State* const L)
{
assert(2 == lua_gettop(L));
auto const i(lualite::class_<C>::getters_.find(lua_tostring(L, 2)));
return lualite::class_<C>::getters_.end() == i
? 0
: (lua_pushlightuserdata(L, &i->second.func),
lua_replace(L, lua_upvalueindex(2)),
(i->second.callback)(L));
}
which looks for the name of the property (which is on the stack). That could be anything really and if it does not find the name, it returns 0, otherwise, it forwards the call to the lualite stub made for the member function, which then handles the arguments and the return value(s).
If you could tolerate having to list the property names in your Lua code, this could be a solution:
local GetPropertyList
do -- to make `property_names` "private" to GetPropertyList
property_names = {
["SpriteComponent"] = { "textureId", "spriteCoordX", "spriteCoordY" },
-- property names for other components, e.g.
["AnotherComponentName"] = { "propName1", "propName2" },
}
function GetPropertyList( object ) --[[local]]
local component_name = object:name()
local prop_names = property_names[component_name]
if not prop_names then
error( "unsupported component" )
end
local res = {}
for _, p_name in ipairs( prop_names ) do
local p_val = object[p_name]
res[ #res + 1 ] = p_val
-- or use this if you want a key-value map:
-- res[p_name] = p_val
end
return res
end -- function
end -- do
for k, v in pairs( GetPropertyList(o) ) do
print( k, v )
end