2

I am unit testing a derived class and want to EXPECT_CALL that a certain method belonging to its base class is called.

For example:

class Base { public: void move(int x, int y); }; class Derived: public Base{ public: RESULT update(); private: int age; }; HRESULT Derived::update(void) { int param1 = 5, param2 = 10; move(param1, param2); age++; return SUCCESS; } 

I can't just create a mock for Derived and expect move since there is no dependency and the actual move() will be called.

How can I be able to mock move()? My end goal is that I need to expect move() to be called with CORRECT parameter values (param1 and param2 in this case).

Of course this isn't the actual code but just a representation

I know this is not good design as far as UT is concerned, but this is to test some legacy code I am not allowed to reformat (but need to make UT). So being able to mock and test move() is the best option I have really.

Help will be appreciated. Thanks!

7
  • Assuming that the test is in a seperate project, you could link the cpp source containing derived, write a custom implementation for base using the base header. Now it will link with the base.cpp with your custom implementation or put move in an interface and depdency inject. Commented Jun 25, 2019 at 9:24
  • 2
    This is testing implementation detail, so it is incorrect approach to write tests. This will make them to much coupled with production code (as a result such tests are pain in the ... in later development). Apparently you have hard or seen mocking and now you are trying forcefully use it. Commented Jun 25, 2019 at 9:35
  • This is just to test some legacy code I can't really refactor. So this is the best option I have really :/ Commented Jun 25, 2019 at 9:47
  • 1
    Adding to @MarekR's comment: think contracts. What contracts does your Derived class respect? For each of its usage, what are the pre- and post-conditions? Your role, as a unit tester, is to check that for any input, if the pre-conditions are respected, Derived respects the post-conditions. Commented Jun 25, 2019 at 9:48
  • Can you make move virtual (for UT)? Commented Jun 25, 2019 at 9:54

2 Answers 2

4

I don't think there is any way without using some preprocessing tricks. And of those tricks making method virtual when testing should be least painfull. It is enough to do something like:

#if UNDER_TEST #define TEST_VIRTUAL virtual #else #define TEST_VIRTUAL #endif class Base { public: TEST_VIRTUAL void move(int x, int y); }; 

Then you can mock it like this:

class TestObject : public Derived { public: MOCK_METHOD2(move, void(int x, int y)); }; TEST(Test, Testing) { TestObject obj; EXPECT_CALL(obj, move(5, 10)); obj.update(); } 
Sign up to request clarification or add additional context in comments.

3 Comments

Making the method virtual will not help in any way.
It will help to mock it. Updated my answer.
Please note that if the derived class will ever be used and then deleted via ptr to the Base class, the dtor in Base class shall be virtual as well.
2

In this code there is noting to mock. You do not have here any external dependency.

Test for this code can look like this:

TEST(DerivedTest, WhenUpdateIsCalledPossitionIsChangedAndItGetsOlder) { Derived foo; foo.age = 1; foo.update(); EXPECT_EQ(10, foo.x); EXPECT_EQ(12, foo.y); EXPECT_EQ(2, foo.age); } 

Show me the reason there is sense to mock here anything?

8 Comments

Sample code above is just a representation of the answer that I need. What I am trying to test is a METHOD of 300+ lines in a legacy code (imagine the pain!). And I am NOT allowed to refactor. So my hands are tied really. Method just returns a plain SUCCESS so I don't know how else to test it. Variables are only local to this method as well so... This is my only option to test what's going on.
Still either you example is not representative or you do not understand mocking. Second version is more probable since first version requires some level of second.
Yes I do understand mocking. I know this is not really the way to go but I can't really do much. I can't just create 1 test expecting SUCCESS when this method just has return SUCCESS in the end :) Code is written almost in C (except for the inheritance) with no intention of UT at all.
My only intention is to be able to check the values at certain points in the code. And the best way I see to test them is by checking the value of the parameters passed in EXPECT_CALL. And AFAIK EXPECT_CALL only works with mocks :/ correct me if I am wrong. I will try to update my sample code.
Updated code doesn't change anything from testing point of view. We only can see that this is Windows code.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.