Search code examples
c++googletest

Expecting a specific thrown exception with Gtest


I am new in using GTest framework. I Want to implement exception handling with one my tests. I've implemented a simple queue data structure equipped with finding a value within the queue. The implementation and calling of the function is below.

queue.cpp

LinkedListNode *CustomDataTypes::Queue::find_value(int value)
{
    auto found = false;
    auto current_node = head;

    try
    {
        if(current_node == nullptr){
            throw new std::runtime_error("Queue is empty");
        }

        // Sequentially check each node
        while (!found){   
            // Compare value
            if(current_node->value == value){
                found = true;
            }else{
                if(current_node->next != nullptr)
                {
                    // If not, then move on to the next node
                    auto next_node = current_node->next;
                    current_node = next_node;
                }else{
                    throw new std::runtime_error("Value does not exist in Queue");
                }
            }
        }
    }
    catch(const std::runtime_error& e)
    {
        std::cerr << "\n ERROR: " <<  e.what() << "\n\n";
    }
    
    // If correct, then return address of the node
    return current_node;
}

main.cpp

// GIVEN: Queue class is filled with 3 elements
auto new_queue = Queue();
new_queue.push_back(1);
new_queue.push_back(2);
new_queue.push_back(3);
.
.
// WHEN: Startup
// THEN: Attempts to find non-existing element in queue
EXPECT_THROW(new_queue.find_value(4), std::runtime_error);

Problem

Expected: new_queue.find_value(4) throws an exception of type std::runtime_error.
  Actual: it throws a different type.

Questions

  1. What am I doing wrong?
  2. Where should the try and catch statement be? In the TEST or queue.cpp scope?

Any tips or advice will be appreciated :)


Solution

  • To summarize the discussion in the comments:

    In C++ you should throw exceptions without the new keyword. Start by replacing throw new std::runtime_error("Value does not exist in Queue"); by throw std::runtime_error("Value does not exist in Queue");

    As pointed out by @Yksisarvinen, try-catching an exception in the same block as it's thrown doesn't make sense. Either throw an exception and handle it in the caller's code, or have a default behaviour for when this error happens and don't throw at all.

    So by removing the try-catch block from the function find_value and throwing without new your test will pass.