I have a function like below:
FnCall(request, response);
where request and reply type are of a class - Message. Now I have mocked the method like below:
class MessageMock : public Message
{
public:
MOCK_METHOD2(FnCall, bool(const Message* request, Message*& response));
};
In my test case I have an expect call to FnCall
EXPECT_CALL(mMessageMock, FnCall(::testing::_,::testing::_));
My requirement is to set some dummy value in the request / response argument in function FnCall of type MessageMock - how can I set that?
=======================================================================
I tried the below code:
MessageMock MessageMock1, MessageMock2;
EXPECT_CALL(mMessageMock, FnCall(&mMessageMock1,
&mMessageMock2));
But receive compilation error and even tried with const declaration:
error: no matching function for call to 'gmock_FnCall(MessageMock*, MessageMock*)'
note: candidate is:
note: testing::internal::MockSpec<bool(const Message*, Message*&)>&
note: no known conversion for argument 2 from 'MessageMock*' to 'const testing::Matcher<Message*&>&'
You are doing this wrong. Your expectation is just on mMessageMock so just that object should be mock. (You are expecting on mock instance) if the test is the caller:
mMessageMock.method(...)
you need to provide dummy objects for that call.
Lets say you have interface like this:
class MyInterface{
public:
virtual void method(MyInterface*, MyInterface*) = 0;
};
and you want to check is some method called on that interface. You define mock class and set expectation on that instance of that mock.
class MyMock : public MyInterface{
public:
MOCK_METHOD2(method, void(MyInterface*,MyInterface*);
};
For your test you need to provide Dummy object to complete interface:
class MyDummy : public MyInterface{
public:
void method(MyInterface*, MyInterface*) override{}
};
So, in your test add:
MyMock mock;
MyDummy request, response;
EXPECT_CALL(mock, method(&request, &response));
and if you want to test this without rest of the code. Just call that method on mock instance after you set expectation.
mock.method(&request,&response);
Here I provide dummy values.
EDIT:
Updated to improve usage of dummy objects.
Related
Assume I got a some Message class object which has nlohmann json as private member and public getter:
class Message{
public:
nlohmann::json getJson() { return json_;}
...
private:
nlohmann::json json_;
...
};
Also there is a class that publishes the message
ex:
class Foo {
public:
publish(const Message& message)
...
};
In the test I am mocking the Foo::publish method and in some scenario I want to check if json_["key1"]["key2"] value is different than "" (empty string)
EXPECT_CALL(
*foo_mock_pointer,
publish(x) // x is the unknown code
);
For checking the value of the json object I guess it will be enough:
testing::Contains(testing::Pair("key1", testing::Pair("key2"), testing::Ne("")))
But I cant figure out how to get the json from Message object which is the argument of the mocked method.
IIUC, it looks like you want to check something about the argument that is passed to your mock function.
You can use SaveArg to save that argument inside a variable and then check its value later:
Message message;
EXPECT_CALL(
*foo_mock_pointer,
publish(x) // x is the unknown code
).WillOnce(DoAll(SaveArg<0>(&message), Return(/*Whatever you want to return*/)));
// Call your class-under-test API here
// ...
// Now check the message:
EXPECT_THAT(message.getJson(), /*Insert your matcher here*/);
See here for more info: http://google.github.io/googletest/gmock_cook_book.html#SaveArgVerify
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 am using junit and mokito to write unit test of my java program.
public MyClass {
private ClassA a;
public void process(ClassB b) {
if(b.method()) a = ClassA.builder().build();
}
}
Now I have write a MockClassA and MockClassB. But I don't know how to :
Pass a MockClassB instantiation to process function
How to verify whether private variable a is set successfully
Can anybody help?
You can use something like:
#Test
public void shouldDoSomething() {
// given
ClassB mock = Mockito.mock(ClassB.class);
Mockito.when(mock.method()).thenReturn(true);
MyClass classUnderTest = new MyClass();
// when
classUnderTest.process(mock);
// then
// Insert assertions
}
However, if your field is private you are unable to test it properly. You should provide a getter for this field if you want to make some assertions against it.
But remember that internal representation of MyClass should not be tested, only the behavior of it so maybe you want to try different approach
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 have a public method that uses a local private method to get data from the Db.
private string SomeMethod(string)
{
...
Doing some operations
...
string data = GetDBData(string);
Doing some operations
...
}
I want to divert/isolate the private method GetDBData(string) using moles so my test will not require the DB.
Obviously, my question is: how to do it?
thank you
Uria
EDIT
Additional information:
i tried to change the method accessors both to public and internal protected,
in both cases i can now see the methods as moles.
BUT when running the test, the original method is still being used and not the detour I've implemented in the PexMethod.
You can try any of the following.
Make the method internal and add an attribute like this to the assembly:
[assembly: InternalsVisibleTo("<corresponding-moles-assembly-name>")]
Change the method access to protected virtual and then use a stub.
Refactor your class so that it gets an interface (IDataAccessObject) as a constructor parameter, SomeMethod being one of the methods of that interface, and then pass a stub of that interface to your class in test methods.
I figured it out
If i have the public MyClass with private SomeMethod
public class MyClass
{
private string SomeMethod(string str){}
}
if you want to mole the SomeMethod method you need to use AllInstances in the test method:
[PexMethod]
SomeMethod(string str)
{
MMyClass.AllInstances.SomeMethod = (instance, str) => { return "A return string"; };
}
notice that the lambda receives an instance parameter as the first parameter. I'm not sure what it's function is.