Search code examples
c++unit-testingtestinggoogletest

How to get Google Test to function properly. Test always fails. (It won't compile)


I got a problem with a unittest in my Google Test application. I want to test if my code produces an exeception if it receives a wrong date or wrong date-format. I used regular expressions with it. I am using Google Test Framework v1.10.0 and TDM GCC (GNU G++ GCC C++ Compiler 9.2.0) and the CodeBlocks IDE 20.03. I am using C++ 11. Using Windows 10.

I get this error when I compile:

||=== Build: Debug in GT_wsDB_Record_Class (compiler: GNU GCC Compiler) ===|
C:\Users\Donald\Documents\CodeBlocks\GT_Original\GT_wsRecord\GT_wsDB_Record_Class\GT_wsRecord_Test.cpp||In member function 'virtual void wsRecords::wsRecordTest_DoesItThrowExceptionWhenWrongDateIsProvided_Test::TestBody()':|
C:\Users\Donald\Documents\CodeBlocks\GT_Original\GT_wsRecord\GT_wsDB_Record_Class\GT_wsRecord_Test.cpp|28|error: expected ';' before '{' token|
..\..\..\GoogleTest\googletest\googletest\include\gtest\internal\gtest-internal.h|1290|note: in definition of macro 'GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_'|
..\..\..\GoogleTest\googletest\googletest\include\gtest\gtest.h|1970|note: in expansion of macro 'GTEST_TEST_THROW_'|
C:\Users\Donald\Documents\CodeBlocks\GT_Original\GT_wsRecord\GT_wsDB_Record_Class\GT_wsRecord_Test.cpp|28|note: in expansion of macro 'ASSERT_THROW'|
C:\Users\Donald\Documents\CodeBlocks\GT_Original\GT_wsRecord\GT_wsDB_Record_Class\GT_wsRecord_Test.cpp|28|warning: statement has no effect [-Wunused-value]|
..\..\..\GoogleTest\googletest\googletest\include\gtest\internal\gtest-internal.h|1290|note: in definition of macro 'GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_'|
..\..\..\GoogleTest\googletest\googletest\include\gtest\gtest.h|1970|note: in expansion of macro 'GTEST_TEST_THROW_'|
C:\Users\Donald\Documents\CodeBlocks\GT_Original\GT_wsRecord\GT_wsDB_Record_Class\GT_wsRecord_Test.cpp|28|note: in expansion of macro 'ASSERT_THROW'|
||=== Build failed: 1 error(s), 1 warning(s) (0 minute(s), 1 second(s)) ===|

I am trying to learn TDD, but I can't seem the test to pass. The productioncode works, it's just the test that doesn't work. I have been working to solve it for 1.5 days already, so trying it this way now.

Hope someone can help me.

Greetings,

Don.

This is the main testfile GT_wsRecord_Test.cpp:

/***************************************/
/* wsDB Record Class - UnitTest        */
/* Framework: Google Test v1.10.0      */
/* Author: D. Voogd - Date: 11-06-2020 */
/***************************************/

#include <gtest/gtest.h>
#include "GT_wsRecord.h"
#include <string>    
namespace wsRecords
{
class wsRecordTest : public ::testing::Test
{
public:

protected:
    weatherdayRecord wsRecord{"2020-10-03"};
};

TEST_F(wsRecordTest,DoIGetTheRightTimeFromTheConstructor)
{
    std::string wsTime = wsRecordTest::wsRecord.getTime();
    ASSERT_EQ(wsTime,"2020-10-03");
}
TEST_F(wsRecordTest,DoesItThrowExceptionWhenWrongDateIsProvided)
{
    ASSERT_THROW(wsRecord{"2002-20-41"},std::invalid_argument);
}
} 

This is the definition file GT_wsRecord.h:

#ifndef GT_WSRECORD_H_INCLUDED
#define GT_WSRECORD_H_INCLUDED

#include <string>

namespace wsRecords
{

class weatherdayRecord
{

public:

// constructor
    weatherdayRecord(std::string time_day);
// destructor
    ~weatherdayRecord();

    // accessors
    std::string getTime() const; // get the time from the day.

    /*
    std::string getWeatherCon() const; // get the weather conditions
    double getMinTemp() const; // get the minimum temperature
    double getMaxTemp() const; // get the maximum temperature
    double getWindSpeed() const; // get the wind speed
    std::string getSymbolVar() const; // get the symbol var for the weather icon
    */

    protected:
    std::string time_day; // date of the day.

    /*
    std::string weather_condition; // weather condition of the day
    double min_temperature; // minimum temperature of the day
    double max_temperature; // maximum temperature of the day
    double wind_speed; // maximum weed speed in meters/sec.
    std::string symbol_var; // symbol that resembles the weather icon
    */
};

}


#endif // GT_WSRECORD_H_INCLUDED

And this is implementation file GT_wsRecord.cpp:

/***************************************/
/* wsDB Record Class - UnitTest        */
/* Framework: Google Test v1.10.0      */
/* Author: D. Voogd - Date: 11-06-2020 */
/* Implementation                      */
/***************************************/

#include <iostream>
#include <regex>
#include "GT_wsRecord.h"
namespace wsRecords{

weatherdayRecord::weatherdayRecord(std::string time_day)
{
 this->time_day = time_day;
}

weatherdayRecord::~weatherdayRecord() {
    ;
}

std::string weatherdayRecord::getTime() const// get the time from the day.
{
    auto const regex = std::regex("((?:19|20)\\d\\d)-(0?[1-9]|1[012])-([12][0-9]|3[01]|0?[1-9])"); // Regex YYYY-MM-DD
    bool const TimeDayContainsRegex = std::regex_search(time_day, regex);
    if(TimeDayContainsRegex == true)
    {
    return time_day;
    }
    else
    {
        throw std::invalid_argument("Wrong date or dateformat.");
    }
}
}

Solution

  • You probably want to do something like this:

    TEST_F(wsRecordTest,DoIGetTheRightTimeFromTheConstructor)
    {
        weatherdayRecord wsRecord{"2020-10-03"};
        std::string wsTime = wsRecord.getTime();
        ASSERT_EQ(wsTime,"2020-10-03");
    }
    TEST_F(wsRecordTest,DoesItThrowExceptionWhenWrongDateIsProvided)
    {
        weatherdayRecord wsRecord{"2020-20-41"};
        ASSERT_THROW(wsRecord.getTime(),std::invalid_argument);
    }
    

    You want to test that the getTime() function throws in the second test, so you first need to create a weatherdayRecord with the bad date (which I think you were trying to do in your original code).

    Note that there's no need for the wsRecord data member. Fixture data members are only necessary when multiple tests need the same object constructed in the same way. In your case you need to construct the weatherdayRecord differently for each test.