Pergunta

Let's say we have the following classes A and B:

class A
{
    virtual void Init() { DoSomething(); }
};

class B : public A
{
    virtual void Init() { DoSomethingSpecial(); A::Init(); }
};

In our unit test we only want to test B, that is to test using Hippomocks that calling B::Init() will actually call DoSomethingSpecial():

B* b_p = new B();
m_mockRepository_p->ExpectCall(b_p, DoSomethingSpecial);
b_p->Init();

Now we don't want to expect all calls from A's Init() so we'd like to write something like:

m_mockRepository_p->ExpectCall(b_p, A::Init);

The last expectation causes an unhandled exception which I think is okay since we are mixing the method we're calling with its base version we want to expect. Casting b_p to an A doesn't help.

Is there any solution to that particular use case?

Foi útil?

Solução

... This is an interesting one. I think there's no solution to this. The call to A::Init isn't done via the virtual function table (as you know explicitly which one to call) so it falls under non-virtual functions, which you cannot mock.

A complicating factor for adding this is that if you took the address of A::Init on B you'd still get the vtable pointer, so you couldn't even replace the function if you wanted to (say, using the C function mocking logic).

I can only recommend the generic refactoring solutions to solve this - make A and B independant classes, make B contain A (private inheritance) or extract an interface from A and B and turn B into a decorator. The last sounds best but it depends on what A and B actually are...

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top