【问题标题】:What is wrong with my attempts to mock a simple C++ method with googlemock?我尝试用 googlemock 模拟一个简单的 C++ 方法有什么问题?
【发布时间】:2011-04-25 16:56:25
【问题描述】:

根据Patterns for unit testing a C++ method that makes a standard library call,我正在测试网络抽象类的开发。为了对进行标准 C 库调用(我无法模拟)以处理 BSD 套接字的代码进行单元测试,我定义了一个接口 ISocket,我的实际实现 CSocket 和模拟 MockSocket 都从该接口继承。

现在我为Network 类编写我的第一个单元测试,它使用ISocket 来完成繁重的工作:

#include "gmock/gmock.h"
#include "gtest/gtest.h"
// C standard library includes omitted
#include "MockSocket.h"
#include "Network.h"

using ::testing::Return;
namespace JrStream {
  class NetworkTest : public ::testing::Test {
  protected:
    Network net;
    ISocket * socket_ptr;

    virtual void SetUp() {
      socket_ptr = new MockSocket();
    }
  };

  TEST_F(NetworkTest, InitCallsSocket) {
    EXPECT_CALL((MockSocket)*socket_ptr, Socket(AF_INET, SOCK_STREAM, 0))
        .Times(1)
        .WillOnce(Return(5)); //fake file descriptor

    ASSERT_TRUE(net.init(socket_ptr));
  }
} // namespace
// gtest boilerplate main() omitted

但我在编译时收到此错误:

g++ -g -Wall -Lgtest-1.5.0/lib -Igmock-1.5.0/include -Igtest-1.5.0/include -I.. -I../../Debug/src -c -o NetworkTest.o NetworkTest.cc
NetworkTest.cc: In member function ‘virtual void JrStream::NetworkTest_InitCallsSocket_Test::TestBody()’:
NetworkTest.cc:35: error: no matching function for call to ‘JrStream::MockSocket::MockSocket(JrStream::ISocket&)’
MockSocket.h:16: note: candidates are: JrStream::MockSocket::MockSocket()
MockSocket.h:16: note:                 JrStream::MockSocket::MockSocket(const JrStream::MockSocket&)

这是我的界面和模拟的样子:

namespace JrStream {
  class ISocket {
    virtual int Socket(int domain, int type, int protocol) = 0;
  };
}

#include "gmock/gmock.h"
#include "ISocket.h"
namespace JrStream {
  class MockSocket: public JrStream::ISocket {
    MOCK_METHOD3(Socket, int(int domain, int type, int protocol));
  };
}

有什么想法我在这里做错了吗?

【问题讨论】:

    标签: c++ unit-testing googlemock


    【解决方案1】:

    看起来您在 TestBody 的某个地方调用了 MockSocket 的复制构造函数,而没有进行强制转换。

    【讨论】:

    • (MockSocket)*socket_ptr...这是一个副本。
    • 好的,这肯定解释了编译器消息......现在我的EXPECT_CALL 应该是什么样子? gmock 不需要指针——如果我说 EXPECT_CALL((MockSocket *)socket_ptr, ...,编译器会抱怨:NetworkTest.cc:35: error: request for member ‘gmock_Socket’ in ‘(JrStream::MockSocket*)((JrStream::NetworkTest_InitCallsSocket_Test*)this)->JrStream::NetworkTest_InitCallsSocket_Test::<anonymous>.JrStream::NetworkTest::socket_ptr’, which is of non-class type ‘JrStream::MockSocket*’
    • 不应该这样工作吗:*static_cast(socket_ptr)?
    【解决方案2】:

    我终于把它整理好了。让我绊倒的是我想使用指针,但 googlemock 与类一起工作。以下是有效的:

    #include "gmock/gmock.h"
    #include "gtest/gtest.h"
    // C standard library includes omitted
    #include "MockSocket.h"
    #include "Network.h"
    
    using ::testing::Return;
    namespace JrStream {
      class NetworkTest : public ::testing::Test {
      protected:
        Network net;
        MockSocket sock;
      };
    
      TEST_F(NetworkTest, InitCallsSocket) {
        EXPECT_CALL(sock, Socket(AF_INET, SOCK_STREAM, 0))
            .Times(1)
            .WillOnce(Return(5)); //fake file descriptor
    
        ASSERT_TRUE(net.init(&sock));
      }
    } // namespace
    // gtest boilerplate main() omitted
    

    这很好,但如果我真的需要我的指点,我想知道如何使它工作。听起来像是对读者的练习。 ;)

    【讨论】:

      【解决方案3】:

      怎么样:

      TEST_F(NetworkTest, InitCallsSocket) {
      EXPECT_CALL(*((MockSocket)*socket_ptr), Socket(AF_INET, SOCK_STREAM, 0))
          .Times(1)
          .WillOnce(Return(5)); //fake file descriptor
      
      ASSERT_TRUE(net.init(socket_ptr));
      

      }

      (免责声明 - 我没有检查它是否编译...)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-10-11
        • 2023-04-02
        • 1970-01-01
        • 2011-07-25
        • 1970-01-01
        • 2021-02-23
        相关资源
        最近更新 更多