модульное тестирование — исключения и BDD в библиотеке Catch

До сих пор я использовал Boost.Test, но сейчас я изучаю использование BDD с Catch, но у меня возникли проблемы с поиском подходящего способа обработки исключений. Скажем, у меня есть такой тест:

SCENARIO("connection handling", "[network]") {
boost::asio::io_service io;
GIVEN("a connection that should fail") {
connection::ptr conn = connection::create(new fake_provider<connection_refused>(io));
WHEN("trying to connect") {
conn->connect("localhost", 1);
THEN("connection was refused") {
some stuff to verify exception code
REQUIRE(conn->connected() == false);
}
}
}
}

Теперь мне интересно, как обрабатывать тот факт, что connect () будет генерировать исключение хорошим способом. Я полагаю, что могу сохранить и сохранить исключение в режиме try-catch и верифицировать в THEN, но это не очень приятно. В моих тестовых случаях Boost.Test я сделал это:

bool error_is_connection_refused(boost::system::system_error ex) {
return ex.code() == boost::system::errc::connection_refused;
}
BOOST_AUTO_TEST_CASE(connect)
{
connection::ptr conn_refuse = connection::create(new fake_provider<connection_refused>(*io_ptr));
BOOST_REQUIRE_EXCEPTION(conn_refuse->connect("localhost", 1),
boost::system::system_error,
error_is_connection_refused);
BOOST_REQUIRE_EQUAL(conn_refuse->connected(), false);
}

Но это не похоже на BDD. Как люди обычно обрабатывают код, генерирующий исключения, когда используют тестирование BDD?

2

Решение

Я немного опоздал с этим, так как я только что заметил тег catch-unit-test 🙂

В настоящее время вы можете сделать:

REQUIRE_THROWS( <expr> );

или для проверки на конкретное исключение тип:

REQUIRE_THROWS_AS( <type>, <expr> );

Если вы хотите проверить содержимое сообщения об исключении … в настоящее время нет способа сделать это, не перехватывая его самостоятельно. Это особенность, которую я подумал добавить.

6

Другие решения

Это как проверить содержание исключения, как предложено philsquared

#include <stdexcept>
#include "catch.hpp"
void my_func(double v)
{
// ...
}

TEST_CASE("wrong params", "[tag]") {
SECTION("wrong rate") {
try {
my_func(1.1);  // must be in range [0..1]
REQUIRE_FALSE("must raise issue about rate");
}
catch(const std::invalid_argument& e) {
std::string str (e.what());
std::string str2 ("rate");
REQUIRE_FALSE(str.find(str2) == std::string::npos);
}
}
}
0