0

I'm trying to mock out a C++ class for testing using Google mock. That class allocates shared memory resources in the ctor, and deallocates them in the dtor. But my mock doesn't need or use those resources.

I can provide a different, protected ctor which doesn't allocate the resources, and this doesn't alter the other already existing ctors. But the dtor will still try to deallocate which fails miserably.

I'm looking for suggestions. I can alter the code under test, I have the source and it's our code. But I'd prefer to alter our production code as little as possible, for 2 reasons: 1) I don't want to risk changing the behaviour so much that I'm not really testing the same code, and 2) this pattern of ctor alloc/dtor dealloc likely occurs many, many time throughout the code and any changes I make might lead to more and more work.

Over-simplified pseudo c++ code example:

class MyClass : MyBaseClass {
    MyClass(int a) : myResource(0) { slowAllocation(myResource, a); }
    // dtor dies horribly if myResources isn't a valid resource
    virtual ~MyClass() { deallocate(myResource); }
protected:
    MyClass() : myResource(0) {} // for test
    MyResourceClass *myResource;
}

Ideas:

A) Alter the dtor so it doesn't dealloc if it's running in test mode. This could be #ifdef'ed out most likely. This might not be too bad, as long as the #ifdef never gets set incorrectly by the build.

B) Stackoverflow faeries vanish my problem before my eyes.

C) Refactor the code, change inheritance and introduce factories such that I can avoid inheriting the dtor code I don't want. I used to write a lot of Java and I'm thinking of the interface/concrete class separation. This could have future benefits too, there are a couple of other cases where I want to derive a class and change the implementation from using a linked list to a concurrent set, but I still have to carry around linked list members (like a head pointer) that I'd no longer use (since I can't un-define data members the way I override methods).

I thought I'd give B) a try, but failing that I'm leaning toward A) - unless the audience sees other problems with that. C) is a lot of work, I'd rather do that only as need case-by-case.

Anyone have experience with a problem like this?

Captain Aporam
  • 315
  • 1
  • 4
  • 13
  • 4
    Is there a particular reason not to do (D) -- allow the mock to allocate the resources even though they aren't used by the mock? You seem to be risking problem (1) ("not testing the real code") in order to reduce the resource use of your test code. Is test efficiency critical? A mock framework is a convenience to make it easier to build mocks. It doesn't promise to build *optimal* mocks! – Steve Jessop Jan 16 '15 at 13:57
  • How about showing a sample of your class interface and the mock class you already have? – πάντα ῥεῖ Jan 16 '15 at 13:59
  • I mainly agree with @SteveJessop, but if you still feel you Really Have To™, then consider replacing the current scheme with a smart pointer (inside the class). Just [one more level of indirection](http://stackoverflow.com/questions/288623/level-of-indirection-solves-every-problem), u now. – Cheers and hth. - Alf Jan 16 '15 at 14:01
  • allow the test to allocate and deallocate the shared memory even if it's not used? – Michael Gazonda Jan 16 '15 at 14:02
  • @SteveJessop yes, the allocation is rather complicated, slow and depends on another executable running. – Captain Aporam Jan 16 '15 at 14:03
  • @CaptainAporam: OK, so there's a tension created by the use of inheritance in mocks. Your base class thinks it's an invariant of the class, that the other executable must be running and the resource must be allocated before any object of that type can be considered successfully initialized. Your mock (which is a derived class) thinks that this is false. Since you can't write your derived class to satisfy the class invariant, change the invariant. Protected ctor that doesn't allocate the memory, and records this fact so the dtor knows not to free. Maybe as simple as `if (resource) { ... }`. – Steve Jessop Jan 16 '15 at 14:08

0 Answers0