GMock GoogleTest - Dieptranivsr/DroneIVSR GitHub Wiki

Advanced Project

dieptt@DESKTOP-BF5GK0T:~/Developments/AdvancedProject$ tree -L 4
.
├── CMakeLists.txt
├── build
├── src
│   ├── CMakeLists.txt
│   ├── calculation
│   │   ├── Calculator.cpp
│   │   └── include
│   │       └── Calculator.hpp
│   └── main.cpp
└── unittests
    ├── CMakeLists.txt
    ├── mocks
    │   └── MockCalculator.hpp
    └── tests
        ├── CalculatorTestSuites.cpp
        ├── CalculatorTests.hpp
        └── main.cpp

7 directories, 10 files
  1. CMakeLists.txt

  2. src/calculation/Calculator.cpp

  3. src/calculation/include/Calculator.hpp

  4. src/main.cpp

  5. src/CMakeLists.txt

  6. unittests/mocks/MockCalculator.hpp

  7. unittests/tests/CalculatorTests.hpp

  8. unittests/tests/CalculatorTestSuites.hpp

  9. unittests/tests/main.hpp

  10. unittests/CMakeLists.txt

CMakeLists.txt

cmake_policy(SET CMP0048 NEW)

project(test_project)

cmake_minimum_required(VERSION 3.16)

set(CMAKE_CXX_STANDARD 17)

include(GNUInstallDirs)

find_package(GTest REQUIRED)

if (${BUILD_UT} MATCHES "On")
    message (STATUS "Building test_project unittest")
    find_library(GCOV_LIB NAMES gcov)
    link_libraries(${GCOV_LIB})
    #find_library(GCOV_LIBRARY NAMES gcov)
    #link_libraries(${GCOV_LIBRARY})
    add_compile_options(-fprofile-arcs)
    add_compile_options(-ftest-coverage)
    add_compile_options(-DBUILD_UT)
    add_subdirectory(unittests)
else()
    message (STATUS "Building test_project release/debug")
    add_subdirectory(src)
    #add_subdirectory(unittests)
endif()

option(ENABLE_CODE_COVERAGE "Enable Code Coverage Flags" FALSE)

set(CODE_COVERAGE_CXXFLAGS "-g;O0;-coverage;-ftest-coverage;-fprofile-arcs;-fprofile-abs-path;-nopipe;" CACHE STRING "Code coverage CXX flags")
set(CODE_COVERAGE_LDFLAGS "-coverage;-ftest-coverage;-fprofile-arcs;" CACHE STRING "Code coverage linker flags")

if(ENABLE_CODE_COVERAGE)
    foreach(_code_coverage_flag IN LISTS CODE_COVERAGE_CXXFLAGS)
        add_compile_options(${_code_coverage_flag})
    endforeach()
    foreach(_code_coverage_flag IN LISTS CODE_COVERAGE_LDFLAGS)
        add_compile_options(${_code_coverage_flag})
    endforeach()
    unset(_code_coverage_flag)
    message(STATUS "Enabling code coverage on all targets, CXX flags: ${CODE_COVERAGE_CXXFLAGS}, LD flags: ${CODE_COVERAGE_LDFLAGS}")
endif()

set(CMAKE_COLOR_DIAGNOSTICS TRUE)

src/calculation/Calculator.cpp

#include "Calculator.hpp"

int Calculator::add(int a, int b) const {
    return a + b;
}

int Calculator::multiply(int a, int b) const {
    return a * b;
}

src/calculation/include/Calculator.hpp

#pragma once

class Calculator {
 public:
    int add(int a, int b) const ;
    int multiply(int a, int b) const ;
};

src/CMakeLists.txt

cmake_minimum_required(VERSION 3.16)

project(project_src VERSION 1.0.0 LANGUAGES CXX)

set(TEST_BINARY_NAME "calculation" CACHE STRING "calculation")

message (STATUS "Building calculation")
add_executable(calculation)
target_sources(calculation PUBLIC
    ${CMAKE_CURRENT_SOURCE_DIR}/calculation/Calculator.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
)

target_link_libraries(calculation
 PUBLIC
    #test-core
)

target_include_directories(calculation
 PUBLIC
    $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}>
    $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/calculation/include>
    #$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/common/include>
)

target_compile_options(calculation 
 PUBLIC
    -Wno-comment
 PRIVATE
    -Werror=uninitialized
    -Werror=return-type
)

install(TARGETS calculation RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" COMPONENT test-service)

src/main.cpp

#include "Calculator.hpp"

#include <iostream>

int main () {
    Calculator a;
    auto b = a.add(10, 12);
    std::cerr << " b = " << b << std::endl;
}

unittests/mocks/MockCalculator.hpp

#include <gmock/gmock.h>
#include <Calculator.hpp>

class MockCalculator : public Calculator {
 public:
    MOCK_METHOD(int, add, (int a, int b), (const));
    MOCK_METHOD(int, multiply, (int a, int b), (const));
};

unittests/tests/CalculatorTests.hpp

#include <gtest/gtest.h>
#include <gmock/gmock.h>

using ::testing::_;
using ::testing::Return;
using ::testing::AtLeast;
using ::testing::MatcherInterface;
// using ::testing::MatcherResultListener;

class CalculatorTestSuite : public ::testing::Test {
 public:
    CalculatorTestSuite() {}
    virtual ~CalculatorTestSuite() {}

    virtual void SetUp() {}
    virtual void TearDown() {}
};

unittests/tests/CalculatorTestSuites.hpp

#include "CalculatorTests.hpp"
#include "MockCalculator.hpp"

// Custom action to log addition results
ACTION_P(LogAddition, message) {
    std::cout << message << arg0 << " + " << arg1 << std::endl;
}

// Custom matcher to check if a number is positive
MATCHER(IsPositive, "") { return arg > 0; }

// Custom matcher to check if greater than threshold
MATCHER_P(IsGreaterThan, threshold, "") { return arg > threshold; }

TEST_F(CalculatorTestSuite, AddOperation_tc1) {
    Calculator calc;
    EXPECT_THAT(calc.add(2, 3), IsPositive());
    // Custom action usage is more applicable to mock objects
}

TEST_F(CalculatorTestSuite, AddOperation_tc2) {
    MockCalculator calc;
    EXPECT_CALL(calc, add(IsGreaterThan(10), _));
    // EXPECT_CALL(calc, add(IsGreaterThan(10), _))
    //     .WillOnce(LogAddition("Addition"));
    calc.add(13, 14);
}

TEST_F(CalculatorTestSuite, MultiplyOperation) {
    Calculator calc;
    EXPECT_EQ(calc.multiply(3, 4), 12);
    // Custom action usage is more applicable to mock objects
}

unittests/tests/main.hpp

#include <gtest/gtest.h>
#include <gmock/gmock.h>

int main(int argc, char **argv) {
    ::testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}

unittests/CMakeLists.txt

message (STATUS "Building test_unittest_bin")

cmake_policy(SET CMP0048 NEW)
cmake_minimum_required(VERSION 3.16)

project(project_unittest VERSION 1.0.0 LANGUAGES CXX)

find_package(GTest REQUIRED)

FILE(GLOB_RECURSE PRJ_SRCS_LIST
    ${CMAKE_CURRENT_SOURCE_DIR}/../src/calculation/Calculator.cpp

    ${CMAKE_CURRENT_SOURCE_DIR}/tests/*.cpp
    ${CMAKE_CURRENT_SOURCE_DIR}/mocks/*.cpp
)

add_executable(unittest_bin)
target_sources(unittest_bin PUBLIC
    ${PRJ_SRCS_LIST}
)

target_include_directories(unittest_bin
 PUBLIC
    $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/mocks>
    $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/tests>
    $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/../src/calculation/include>
)

target_link_libraries(unittest_bin
 PUBLIC
    GTest::gtest GTest::gtest_main GTest::gmock GTest::gmock_main
)

set_target_properties(unittest_bin PROPERTIES
    CXX_STANDARD 17
    OUTPUT_NAME test-unittest
)

install(TARGETS unittest_bin RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" COMPONENT test_unittest)
⚠️ **GitHub.com Fallback** ⚠️