1

I've created a class in which there's some new operator in the constructor. I've created the guard into the constructor to manage new operator failing, but now I want to test it.

As example, I've a constructor that is like this:

Function::Function()
{
  try
  {
    m_pxArgument = new Argument();
  }
  catch(std::bad_alloc)
  {
    throw MemoryException();
  }
}

Is it possible to create a test in which I can tell the new operator to fail, to test my catch code?

Jepessen
  • 11,744
  • 14
  • 82
  • 149
  • I'm not an expert programmer, but I think it is better to use the `try` outside your constructor... –  Sep 16 '12 at 09:27
  • `Argument` is your class/struct? – PiotrNycz Sep 16 '12 at 09:34
  • It's only an example, but the try statement must stay inside because the real class is more complex and I want to handle library specific exceptions. std::bad_alloc in this case is a valid exception, but it's thrown by internal management that's not good, in my opinion. User must does not know anything about class internals, and so for internal exceptions. – Jepessen Sep 17 '12 at 13:40
  • Argument is standard. I've another constructor in which I specify what Argument() the object must use, but it's ok in my implementation to have a default one. – Jepessen Sep 17 '12 at 13:41

2 Answers2

4

If Argument is your class/struct - then define operator new in this class just for UT purposes.

class Argument {
//...
#ifdef UNIT_TEST
   static bool& failNew() { static bool failNew = false; return failNew; }
   void* operator new(size_t size)
   {
       if (!failNew())
         return ::operator new (size);
       failNew() = false;       
       throw std::bad_alloc("Argument");
   }
#endif
};

Just set Argument::failNew() = true; every time you need to fail its allocation.

jogojapan
  • 68,383
  • 11
  • 101
  • 131
PiotrNycz
  • 23,099
  • 7
  • 66
  • 112
1

To do such a test you would need to overload operator new for your class Argument and then provide a definition that throws in your test case. However, since that can not be easily exchanged at run time you might need a separate test program.

If you would be my C++ student, I would first ask, why you use new and a may be "naked" pointer member variably anyway. A First choice would be to create a member variable of type Argument and skip explicit heap allocation. If you really need dynamic allocation in modern code I'd recommend to use shared_ptr<Argument> and Function::Function():m_pxArgument(make_shared()){}

The second question I would like to ask, is why you want to translate std::bad_alloc to your own exception type and if that needs to be done in the constructor. std::bad_alloc is standardized exception for the situation that you actually encounter and if that happens, live is usually bad enough that your little process can not do much to recover (see the pattern "Captain Oates" by Charles Weir and James Noble).

PeterSom
  • 2,067
  • 18
  • 16
  • Hi. At first, as I've said, this is only an example. My real class is a bit more complex and the new operator is needed. But I'll check for share_ptr, thanks for this suggestion. For your second reply, I want to to this because I want to give an uniform exception management for the library, and in this case a generic memory exception is preferred in my opinion, because it does not give details about internal implementation, that can change over time. – Jepessen Sep 16 '12 at 10:08