I am currently using HippoMocks as mocking framework, and can't figure out how to mock the pure virtual method MockMe()
in the code below. I do not want to mock any of the non-virtual methods (which is likely not even possible), instead I want them to do what they are meant for and call the mocked virtual one.
struct A
{
void Run() { RunImpl(); }
virtual void RunImpl() = 0;
};
struct B : public A
{
//implement A::RunImpl
void RunImpl() { MockMe(); }
//this one I want to mock
virtual void MockMe() = 0;
};
MockRepository mocks;
B* b = mocks.开发者_Go百科InterfaceMock< B >();
mocks.OnCall( b, B::MockMe );
b->Run(); //throws NotImplementedException for Run()
Is there any way to get this working with HippoMocks? Or with another framework? Or with some source modifications?
I haven't used mocking frameworks, but this should be one of the easier things to do...
Extend the B
class with a Mock
class, where you only override the pure virtual methods and forward on the constructors. Then instantiate the derived class and pass it as a reference/pointer to the mocked class, which is something the rest of the application is probably ready to handle: if the class has pure virtual functions, then the application is using it polymorphically, through pointers and/or references.
update/answer: I found a way around it by deriving a new class from B and adding a helper to forward the calls to the appropriate method. Apart from that it's also important to use ClassMock
instead of InterfaceMock
.
So, using the example above, this works:
struct MockHelper : public B
{
void InvokeRunImpl()
{
B::RunImpl();
}
virtual void MockMe()
{
//never called, but must be defined so MockHelper can be instantiated
}
};
MockHelper* b = mocks.ClassMock< MockHelper >();
auto invokeIt = [b]() { b->InvokeRunImpl(); };
mocks.OnCall( b, MockHelper::RunImpl ).Do( invokeIt );
mocks.OnCall( b, MockHelper::MockMe );
//ok now: calls A::Run, which calls mocked RunImpl, which in turn
//calls InvokeRunImpl, which in turn calls B::RunImpl
b->Run();
精彩评论