c++ 单元测试中gmock-global的多重定义

mutmk8jj  于 2023-05-19  发布在  其他
关注(0)|答案(3)|浏览(202)

我正在尝试使用https://github.com/apriorit/gmock-global库模拟全局函数。
注:本说明包含真实的场景的示例,而不是确切的真实场景。此外,我不允许对global. hpp进行任何更改。
我的示例目录结构如下所示

--src
------global.hpp
------classA.hpp
------classB.hpp
------main.cpp
--ut
------classATests.cpp
------classBTests.cpp
------main.cpp

ut/main.cpp测试classATests.cpp和classBTests.cpp中的测试用例。
hpp包含一个全局函数

int giveIndex()
{
    return 1;
}

hpp调用giveIndex()全局函数

#include "global.hpp"
class A
{
public:
int checkIndex() { return giveIndex(); };
}

hpp调用giveIndex()全局函数

#include "global.hpp"
class B
{
public:
int checkIndex() { return giveIndex(); };
}

classATests.cpp包含

#include <memory>
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include <gmock-global/gmock-global.h>
#include "src/classA.hpp"
MOCK_GLOBAL_FUNC0(giveIndex, int(void));

using namespace ::testing
struct classATests : public ::testing::Test
{
    void Setup() override
    {
        sut_ = std::make_shared<A>();
    }
    std::shared_ptr<A> sut_;
};
TEST_F(classATests , checkIndex)
{
    EXPECT_GLOBAL_CALL(giveIndex, giveIndex()).WillOnce(Return(1));
    sut_->checkIndex();
}

classBTests.cpp包含

#include <memory>
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include <gmock-global/gmock-global.h>
#include "src/classB.hpp"
MOCK_GLOBAL_FUNC0(giveIndex, int(void));

using namespace ::testing
struct classBTests : public ::testing::Test
{
    void Setup() override
    {
        sut_ = std::make_shared<B>();
    }
    std::shared_ptr<B> sut_;
};
TEST_F(classBTests , checkIndex)
{
    EXPECT_GLOBAL_CALL(giveIndex, giveIndex()).WillOnce(Return(1));
    sut_->checkIndex();
}

现在的问题是,当我为classATests.cpp和classBTests.cpp编译并运行UT时,我会得到以下错误:
...'giveIndex'的多个定义;和... gmock_globalmock_giveIndex_instance的多个定义
有没有办法避免这个问题?classA测试和classB测试需要像现在一样在2个不同的文件中。

jv4diomz

jv4diomz1#

头文件中定义的函数应该内联定义

inline int giveIndex()
{
    return 1;
}

否则,如果你不止一次地包含头文件,你将得到多个定义错误。
另一种方法是只在头文件中声明函数

int giveIndex();

然后在一个cpp文件中定义它(但不是内联)。
这是组织C++代码的正常方式。gmock和这件事无关。

ztyzrc3y

ztyzrc3y2#

当我在头文件中声明了一个函数并在.cpp文件中定义时,我遇到了这个问题。
这是由于在我的测试cmake文件的目标中包含了.cpp文件而导致的。一旦我删除它,一切都正确编译,函数被正确地模拟。

问题基本示例:

add_executable(
    test_executable
    test.cpp
    file_with_function_to_mock.cpp
    ...
)

修复:

add_executable(
    test_executable
    test.cpp
    ...
)

我猜,如果你试图测试cpp文件中的一个函数,同时模拟同一文件中的另一个全局函数,你也会遇到这个问题。在这种情况下,您将不得不重新编写源代码以使其更易于测试。无论是将要模拟的函数移动到另一个文件,还是将函数 Package 到类层次结构中。

jhkqcmku

jhkqcmku3#

你的程序有1个翻译单元,你的测试有3个。global.hpp不能包含在多个转换单元中,所以如果你不能修改它,你的测试结构将不得不改变,这样ut/main.cpp就是你的测试可执行文件中唯一包含global.hpp的转换单元。

--src
------global.hpp
------classA.hpp
------classB.hpp
------main.cpp
--ut
------classATests.hpp
------classBTests.hpp
------main.cpp

ut/main.cpp:

#include "classATests.hpp"
#include "classBTests.hpp"

// existing stuff

更可取的情况是认为global.hpp从根本上损坏了,您需要修复它,因为john's回答了细节。

相关问题