简体   繁体   中英

C++ how can I refactor this?

I have the code below in my test code in many places:

  //
  // Make a function call while expecting an exception should be thrown
  //
  bool exceptionThrown = false;
  try
  {
    expectNotEqual(someData, anotherData, methodName);
  }
  catch(std::logic_error&)
  {
    exceptionThrown = true;
  }
  if(!exceptionThrown)
    throw std::logic_error(methodName+"exception not thrown");

It would be nice (more readable, concise) if I could encapsulate all that, and do something like:

  exceptionShouldBeThrown(expectNotEqual(someData, anotherData, methodName));

I dont want to use macro ...does anyone know how I could achieve the one-liner above with C++?

I know you say no macro's, but why? They exist for generating code:

#define SHOULD_THROW(x, name) \
    { \
        bool didThrow = false; \
        try \
        { \
            x; \
        } \
        catch(...) { didThrow = true; } \
        \
        if (!didThrow) \
            throw std::logic_error(name " did not throw."); \
    }

SHOULD_THROW(expectNotEqual(someData, anotherData), "expectNotEqual")

If you really don't want to use macros, you need to make a functor to call:

template <typename Func>
void should_throw(Func pFunc, const std::string& pName)
{
    bool didThrow = false;
    try
    {
        pFunc();
    }
    catch (...)
    {
        didThrow = true;
    }

    if (!didThrow)
        throw std::logic_error(pName + " did not throw.");
}

Boost Bind helps here:

should_throw(boost::bind(expectNotEqual, someData, anotherData),
                "expectNotEqual");

Of course anything that makes a functor works, like lambda's, etc. But if Boost is available, just use their testing library :

#define BOOST_TEST_MAIN
#include <boost/test/unit_test.hpp>

BOOST_AUTO_TEST_CASE(test)
{
    BOOST_CHECK_THROW(expectNotEqual(someData, anotherData) , std::logic_error);
}

Exceptions are for things that are exceptional. That is, something you wouldn't expect during run time, eg, out of memory error. You don't want to use an exception to test for common things at run time. Just have expectNotEqual return a true/false on success:

if (expectNotEqual(someData, anotherData, methodName))
{
  //handle success
}
else
{
  //handle failure (which would include someData==anotherData)
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM