C ++:检查是否在没有外部库的情况下抛出了某种异常类型

时间:2013-11-04 23:24:37

标签: c++ exception testing

我正在为C ++程序编写一些测试,我想检查一下我的程序在给定某些输入时会抛出某些类型的异常。我已经看到使用googletest等外部库这是可行的,但我想知道这是如何实现的。

我想尽可能地将测试数据与测试代码分开。特别是,我想要这样的事情:

void RunTests(InputList inputs) {
    for (int i = 0; i < inputs.length; i++) {
        if (FunctionIAmTesting(inputs[i].value) has the expected exception behavior) {
            // Pass
        } else {
            // Fail
        }
    }
}

InputList inputs = InputList({
     Input(5),                         // no exception when 5 is an input
     Input<MyExceptionClass>(0),       // MyExceptionClass thrown when 0 is an input
     Input<MyOtherExceptionClass>(-1)  // MyOtherExceptionClass thrown when -1 is an input
});

RunTests(inputs);

2 个答案:

答案 0 :(得分:2)

如果您知道要查找的异常类型,那么您可以在catch ()语句中定位该类型的异常。

try {
    // Test code.

    // Unexpected success
    std::cerr << "Expected a RelevantException to be thrown." << std::endl;
}
catch (RelevantException& e)
{
    // Expected exception, continue.
}
catch (...) // Catch all
{
    // Unexpected exception
    std::cerr << "Unexpected exception encountered, expected "
                 "RelevantException." << std::endl;
}

答案 1 :(得分:0)

几年前,我为“嘲弄”对象写了一些简单的库。我的目标是检查与函数调用相关的所有内容。在测试中我写了类似的东西:

MyMockedObject my;
mock::expect(my, "foo").in(10).out(20).returns(30);
mock::expect(my, "bar").throws(logic_error("bar failed"));

int v;
// test that my::baz() invokes my.foo(10, v)
// then my.bar which fails with the exception
my.baz();

您的任务似乎更容易一些。您需要的只是一种如何描述您的期望和一些黑客入侵测试运行器以在测试结束时验证它们(相应于输入)的方法。您的期望是例外,只是以某种方式构建它们并与输入相关联。在你的例子中,你做了半部分工作。

typedef std::map<Input, Exception> Expectations;
typedef std::pair<Input, Exception> Expectation;

// somewhere before the tests
expectations.insert(make_pair(Input(5)), NoThrowAnything);
expectations.insert(make_pair(Input(0)), MyException("some message"));
expectations.insert(make_pair(Input(-1)), MyOtherException("another message"));

void run_test(const Expectation& expect)
{
  try {
    // run the real test here based on Input (expect.first)
    check_expectation(expect);
  } catch (const Exception& ex) {
    check_expectation(expect, ex);
  }
}

void run_all_tests(const Expectations& expects)
{
  for (e : expects) {
    try {
      run_test(e);
    } catch (const ExpectationException ex) {
       // failed expectation
    }
  }
}

void check_expectation(const Expectation& expect)
{
  if (expect.second != NoThrowAnything) {
    throw ExpectationFailure(expect);
  }
}

void check_expectation(const Expectation& expect, const Exception& ex)
{
  if (expect.second != ex) {
    throw ExpectationMismatch(expect, ex);
  }
}