【问题标题】:Google Mock to test the real behaviors of a classGoogle Mock 测试类的真实行为
【发布时间】:2014-10-21 16:07:48
【问题描述】:

我是谷歌测试和谷歌模拟的新手,所以我还是有点困惑。我只是尝试用整数加法、乘法和除法实现一个简单的计算器,并为它创建一个遵循真实行为的模拟。我该如何解决它或我做错了什么?

您还可以向我解释一下如何确定它是在模拟原始类而不是直接调用原始类?提前谢谢你。

这里是 CBasicMath.hpp:

#ifndef BASIC_MATH_HPP__
#define BASIC_MATH_HPP__

class CBasicMath
{
public:
    CBasicMath(){}
    virtual ~CBasicMath() {}
    virtual int Addition(int x, int y);
    virtual int Multiply(int x, int y);
    virtual int Divide(int x, int y);
};

#endif //BASIC_MATH_HPP__

这里是 CBasicMath.cpp:

#include "CBasicMath.hpp"

int CBasicMath::Addition(int x, int y)
{
   return (x + y);
}

int CBasicMath::Multiply(int x, int y)
{
   return (x * y);
}

int CBasicMath::Divide(int x, int y)
{
   return (x / y);
}

这里是 mock_basic_test.cpp:

#include "gmock/gmock.h"
#include "CBasicMath.cpp"

using ::testing::_;
using ::testing::AtLeast;
using ::testing::Invoke;

class MockBasicTest : public CBasicMath {
public:
    MockBasicTest() {
    // By default, all calls are delegated to the real object.
    ON_CALL(*this, Addition(_))
        .WillByDefault(Invoke(&real_, &CBasicMath::Addition));
    ON_CALL(*this, Multiply(_))
        .WillByDefault(Invoke(&real_, &CBasicMath::Multiply));
    ON_CALL(*this, Divide(_))
        .WillByDefault(Invoke(&real_, &CBasicMath::Divide));
  }
    MOCK_METHOD2(Addition, int(int x, int y));
    MOCK_METHOD2(Multiply, int(int x, int y));
    MOCK_METHOD2(Divide, int(int x, int y));
private:
    CBasicMath real_;
};

这里是 TestBasicMath:

#include "mock_basic_test.h"
#include "gtest/gtest.h"
#include "gmock/gmock.h"

class BasicMathTest : public ::testing::Test {
protected:
    BasicMathTest() {}

    virtual ~BasicMathTest() {}

    virtual void SetUp() {
        mTestObj = new CBasicMath();
    }

    virtual void TearDown() {
        delete mTestObj;
    }
    CBasicMath *mTestObj;
};

TEST_F(BasicMathTest, testAddition) {
    MockBasicTest basictest;
    EXPECT_CALL(basictest, Addition(2,3))
        .Times(1);
    EXPECT_EQ(5,basictest.Addition(2,3));
}

TEST_F(BasicMathTest, testMultiply) {
    EXPECT_EQ(6,mTestObj->Multiply(2,3));
}

TEST_F(BasicMathTest, testDivide) {
    EXPECT_EQ(6,mTestObj->Divide(6,1));
}

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

它给我所有三个函数的错误如下:

In file included from /home/gmock-1.7.0/include/gmock/gmock-generated-function-mockers.h:43:0,
                 from /home/gmock-1.7.0/include/gmock/gmock.h:61,
                 from mock_basic_test.h:1,
                 from TestBasicMath_GoogleTest.cpp:1:
mock_basic_test.h: In constructor ‘MockBasicTest::MockBasicTest()’:
mock_basic_test.h:12:30: error: no matching function for call to ‘MockBasicTest::gmock_Addition(const testing::internal::AnythingMatcher&)’
     ON_CALL(*this, Addition(_))
                             ^
mock_basic_test.h:12:30: note: candidate is:
In file included from /home/gmock-1.7.0/include/gmock/gmock.h:61:0,
                 from mock_basic_test.h:1,
                 from TestBasicMath_GoogleTest.cpp:1:
mock_basic_test.h:19:2: note: testing::internal::MockSpec<int(int, int)>&MockBasicTest::gmock_Addition(const testing::Matcher<int>&, const testing::Matcher<int>&)
  MOCK_METHOD2(Addition, int(int x, int y));
  ^
mock_basic_test.h:19:2: note:   candidate expects 2 arguments, 1 provided

再次感谢您的帮助。

【问题讨论】:

  • 你的 include-guard 是非法的,详情见here
  • @BaummitAugen 模仿系统头文件的人注定是UB。
  • @BaummitAugen 谢谢。我改成 BASIC_MATH_HPP_ 还是不行。
  • @caiy “谢谢。我改成了 BASIC_MATH_HPP,但它仍然不起作用。”_ 这是一个有效的,但关于原始问题的次要问题,不应该被视为解决您问题的答案。

标签: c++ unit-testing googletest googlemock


【解决方案1】:

在你的模拟类构造函数代码中

ON_CALL(*this, Addition(_))
    .WillByDefault(Invoke(&real_, &CBasicMath::Addition));

匹配器的数量(_)需要与为函数签名定义的参数数量相同:

ON_CALL(*this, Addition(_,_))
                    //   ^^  Add an additional matcher
    .WillByDefault(Invoke(&real_, &CBasicMath::Addition));

// ...

MOCK_METHOD2(Addition, int(int x, int y));
                        // ^^^^^  ^^^^^ here you have 2 parameters need matching

【讨论】:

  • 非常感谢您的帮助。你知道是否有一种更简单的方法来模拟真实行为,因为我有一个非常大的项目需要测试。再次感谢您。
  • @caiy 另请注意:您将当前课程作为模拟委托进行测试的方式对我来说有点奇怪。通常,您只需为每个测试用例提供一个测试实例,并提供模拟,这些模拟预计将从特定成员函数调用的这些模拟中调用。
  • 我不确定你的意思。你能给我一个例子或重组我的课程来给我看吗?谢谢。
  • @caiy 您的示例测试现在看起来,您不需要模拟对象。为什么不简单地测试一个真实类CBasicMath 的实例?例如。 CBasicMath cbm; EXPECT_EQ(5,cbm.Addition(2,3));.
  • 我有更复杂的类要作为整个项目进行测试。他们对他们有很多依赖。所以我只是通过这个简单的类来测试一下 gtest 和 gmock 的功能。
【解决方案2】:

这仅在可以默认构造“T real_”时才有效。此外,您会在您的模拟中获得另一个 T 副本,这不是必需的。

恕我直言,您可以这样做,因为您以任何一种方式访问​​基类:

ON_CALL(*this, Addition(_))
    .WillByDefault(Invoke(*this, &CBasicMath::Addition));

这样调用只是委托给基类。

【讨论】:

    猜你喜欢
    • 2015-12-25
    • 1970-01-01
    • 2023-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-20
    • 1970-01-01
    相关资源
    最近更新 更多