1

我正在为 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);
4

2 回答 2

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;
}
于 2013-11-04T23:34:33.683 回答
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);
  }
}
于 2013-11-05T00:04:21.287 回答