I just started working on unit testing using googleTest.
I have a situation where I have a static method of one class is calling inside the other class
class A {
public:
static bool retriveJsonData(std::string name, Json::Value& responseJsonData);
}
In other class i am using the Class A retriveJsonData method.
class B {
public:
bool Method1 (std::string name) {
Json::Value sampleJsonData;
return A::retriveJsonData(name, sampleJsonData);
}
Mocking of class A
class MockA : public A {
public:
MOCK_MEHTOD2(retriveJsonData, bool(std::string, Json::Value));
}
Now I have to mock retriveJsonData in Testing of Method2 of class B using EXPECT_CALL.
Please help me to resolve how can I test this situation?
Google Mock's mock types provide ways to check expected calls for non-static member functions, where either virtual function polymorphism or templates can be used as a "seam" to swap in the mock functions for real functions. Which is great if you can design or refactor everything to use one of those techniques. But sometimes it would be cumbersome to get things working that way in messy legacy code or in code using an external library, etc.
In that case, another option is to define a dependency function which is not a non-static member function (so either a free function or a static member) to redirect to some singleton mock object. Assume we have some translation unit (B.cpp) to be unit tested, and it calls some non-member or static member function (A::retrieveJsonData) not defined in that translation unit.
Normally, to unit test B.cpp, we would note its required linker symbols and provide fake definitions for them that stub them out, just to get the object file B.o to link into the unit test program:
// Fake definition:
bool A::retrieveJsonData(std::string, Json::Value&)
{ return false; }
In this case, we don't want that fake definition; we'll define it later to redirect to a mock object.
Start with a mock class specifically for the problematic function calls. If there are other non-static member functions to test the ordinary way, this class is NOT the same as those classes. (If this is needed for more than one function, these mock classes could be done per function, per class and/or one for free functions, per library, one for everything; however you want to set it up.)
class Mock_A_Static {
public:
Mock_A_Static() {
EXPECT_EQ(instance, nullptr);
instance = this;
}
~Mock_A_Static() {
EXPECT_EQ(instance, this);
instance = nullptr;
}
MOCK_METHOD2(retrieveJsonData, bool(std::string, Json::Value&));
private:
static Mock_A_Static* instance;
friend class A;
};
Mock_A_Static* Mock_A_Static::instance = nullptr;
// The function code in B.cpp will actually be directly calling:
bool A::retrieveJsonData(std::string name, Json::Value& responseJsonData)
{
EXPECT_NE(Mock_A_Static::instance, nullptr)
<< "Mock_A_Static function called but not set up";
if (!Mock_A_Static::instance) return false;
return Mock_A_Static::instance->retrieveJsonData(name, responseJsonData);
}
Then just put an object of that type local to a test, or in a fixture class. (Only one at a time, though!)
TEST(BTest, Method1GetsJson)
{
Mock_A_Static a_static;
B b;
EXPECT_CALL(a_static, retrieveJsonData(StrEq("data_x"), _));
b.Method1("data_x");
}
Use A as a template parameter in class B (see Modern C++ Design).
template <class T>
class B {
public:
bool Method1 (std::string name) {
Json::Value sampleJsonData;
return T::retriveJsonData(name, sampleJsonData);
}
}
then in your tests use:
B<MockA> b;
In production code:
B<A> b;
You can't use MOCK_MEHTOD2 with static methods.
You can define a private method in B that just call retriveJsonData:
Class B
{
public:
bool Method1 (std::string name) {
Json::Value sampleJsonData;
return retriveJsonData(name, sampleJsonData); };
private:
bool retriveJsonData(std::string name, Json::Value& responseJsonData) {
return A::retriveJsonData(name, responseJsonData); };
};
Then you can write a test class to be used in your test instead of B:
Class Test_B : public B
{
MOCK_METHOD2( retriveJsonData, bool(std::string name, Json::Value& responseJsonData));
};
This situation is very common in real development. To isolate a target class the gmock is very useful but also very limitted.
However, if you don't want to change any of the class A and B, here is the one of the solution by using "jomock" without changing A and B at all.
// let's say there are class A and B in legacy code.
class A {
public:
static bool retriveJsonData(std::string name, Json::Value& responseJsonData);
}
class B {
public:
bool Method1 (std::string name) {
Json::Value sampleJsonData;
return A::retriveJsonData(name, sampleJsonData);
}
// unit test code below
#include "jomock.h"
TEST(JoMock, staticFnTest)
{
EXPECT_CALL(JOMOCK(A::retriveJsonData), JOMOCK_FUNC(_,_))
.Times(Exactly(1))
.WillOnce(Return(false)); // return false once.
EXPECT_EQ(B::Method1("arg"), false);
}
Related
I am coding in C++11 and I have a large parent non-static function and I want to reuse it in my derived class.
The parent non-static function uses a static function defined in itself. I have overloaded the static function in my derived class and I want the parent non-static function to use the static function of the derived class. But it doesn't and uses its own version. A similar question was asked but this is different in the sense that it deals with static as well as non-static members of a class. For example, see the sample code below:
#include <iostream>
class Base
{
public:
static int value() { return 0; }
int getValue() { return value(); }
};
class Derived:public Base
{
public:
static int value() { return 1; }
};
int main()
{
Derived obj;
std::cout << obj.getValue() << std::endl;
return 0;
}
I want the code the print 1 but it prints 0
Is there any way I can do that? Thanks a lot for helping.
Update #1
For me, the getValue() function is quite big, which is why I asked the question in the first place. Overriding the getValue() function in the derived class, as suggested in the comments might be a feasible option but for me, it would be copying a large function multiple time, since I have multiple derived classes, which would make it cumbersome to make changes in the future. Briefly saying,
I want to define a non-static, public function once in a parent class which uses a static member of the class, and then reuse the non-static function in every child class in such a way that in case I overload the static function of the parent class in the child class, the non-static function of the parent class uses the overloaded function.
I read that one advantage of using by "inheritance" for generic-code is "the fact that the type of the object determined in runtime", because that allows more flexibility.
I don't understand this point. How it's really allows more flexibility?
If for example I get object from type that derived Base , so that:
class Base{
public:
virtual void method() const { /* ... */ }
};
class D1 : public Base{
public:
void method() const override { /* ... */ }
};
class D2 : public Base{
public:
void method() const override { /* ... */ }
};
And I send to function f (for example) the following object:
Base* b = new D1;
f(b);
Where is the flexibility (What it's defined as advantage that it's done in runtime) ?
Your example isn't demonstrating it, but it could.
f(b) could be
void f(Base* b) {
b->method();
}
Now, the actual method() code that's executed is determined at runtime by the type of the object that's passed in.
How it's really allows more flexibility?
It's more flexible because the author of f(..) doesn't need to know how Base:method() works in any specific case: You can add D3, D4, D5 classes with new implementations of method() without f(..) ever needing to know or change.
I am using Gtest for unit testing. There are some methods which return an object. Example is shown below
Class ToTest{
public:
object& method(){
object* obj = new object();
return obj;
}
}
"ToTest" is the class that is to be tested. It has a method which returns an object "obj". How can i validate this object using Gtest ?
So, you want to test a singleton. As you see, there is almost nothing to test there. You can call that method, and that is it. There is nothing to validate, except there are no leaks (by executing the unit test program using valgrind or similar tool).
class ToTestTest : public testing::Test
{
public:
ToTestTest()
{
}
~ToTestTest()
{
}
ToTest obj;
};
TEST_F( ToTestTest, method )
{
obj.method();
}
I've got a simple mixin, which I am mixing in to my other template classes.
template<typename T> class mixin {
static T* null() { return nullptr; }
auto func() -> decltype(null()->func());
};
template<...> class A : public mixin<A<...>> {
....
};
template<...> class B : public mixin<A<...>> {
....
};
template<...> class C : public mixin<A<...>> {
....
};
Now, I've got a problem. One of the mixin functions will return a type which must be deduced depending on the derived type. But when I attempt to use deduction to find this type, the compiler tells me that I am using an undefined type. If I move the definition of mixin to be after the classes, then I won't be able to inherit from it when mixing in. How can I change my classes to allow type deduction in this case?
I don't believe there's any way to make this work. You have a cyclic dependency between the types of each class. A needs the definition of mixin<A<...>> and mixin<A<...>> needs the definition of A.
In my opinion, you would be best just to manually specify the type in the mixin parameters.
For example:
template<typename ReturnType> class mixin
{
auto func() -> ReturnType;
};
template<...> class A : public mixin<int>
{
int func();
};
I want to be able to move an instance method from one class to another class ("Move method" from Fowler's "Refactoring") in IntelliJ IDEA. Unfortunately, when I try "Move..." (cmd: F6), it tells me that "There are no methods that have a reference type. Would you like to make method static and then move?" I do not want to make my method static, I want it to be an instance method on the other class instead.
My code example:
public class TheClass {
public void doStuff(){
int i = themethod();
}
private int theMethod() {
System.out.println( "Hello World!" );
return 0;
}
}
public class OtherClass {
}
Say I want to move theMethod from TheClass to OtherClass. Is there an automatic refactoring in IDEA for this, and if so: How do I apply it?
In IntelliJ 14-15 do the following:
Position the caret on theMethod().
press Ctrl/Cmd+F6 (Change signature).
Introduce new parameter: Type=TheOtherClass, Name=theOtherClass, Default value=new TheOtherClass()
Refactor
Then press F6 (move) and move the method to theOtherClass.
You will end up with:
public class TheClass {
public void doStuff() {
int i = new TheOtherClass().theMethod();
}
}
public class TheOtherClass {
int theMethod() {
System.out.println("Hello World!");
return 0;
}
}
The Move Method refactoring in IDEA only considers moving the method into classes related to it, i.e. used as its parameter or return value, or called from inside the method. Which is kinda logical: if the method has nothing concrete to do with the target class, why should it be there? OTOH I found this limiting in some cases where I still had a valid reason to move the method. So I had to do it by hand.
In intellij 13.1 (dont' know in previous version) it could be done with the
Choose Refactor | Extract | Delegate on the main menu
but there is a "strange" limit, apparently: it could be done only with a new freshly created class.
So you have to do apply this refactoring without creating the "OtherClass" (it will be create directly when you apply the refactoring).
So a real "move" of method on an alredy created class seems missing, quite strange behaviou
if theMethod() has nothing reference to the host class(TheClass), you can make this method static and then use "Move" command. After the method was moved to the target class, you should remove the static keyword.
There is another method. Imagine you have the code:
public int field;
public void foo(int a) {
assert field == a;
}
And you want to make foo static. Select the whole body of the method and preess Alt+Ctrl+M (Extract method). Type the same name of the method. Check "Declare static" checkbox (available only if the method only reads and doesn't modify the fields) and press Ok. So you get:
public void foo(int a) {
foo(a, field);
}
private static void foo(int a, int field) {
assert field == a;
}
Move static method wherever you want and use old foo's body to call it.