期望在C ++中使用GoogleMock的参考对象的匹配器

时间:2016-01-30 02:02:35

标签: c++ mocking

我正在尝试使用模拟来测试使用某些参数调用某个方法,并且在测试*this是其中一个参数时遇到问题。

以下是测试中的代码:

class Component
{
  virtual void update(Entity &entity, const uint32_t dt) {};
  ...

void Entity::update(const uint32_t dt)
{
  for (unsigned int i = 0; i < components_.size(); ++i) {
    components_[i]->update(*this, dt);
  }
}   

测试:

ea_ = new aronnax::Entity(cla_);
EXPECT_CALL(mockComponent, update(Eq(ByRef(ea_)), testDt)).Times(1);
ea_->update(testDt);

我遇到两种类型无法比较的错误。我对c ++比较陌生,并且无法理解如何将指针ea_与指针引用(*&)与传递到ea_的{​​{1}}进行比较。

2 个答案:

答案 0 :(得分:0)

这是一个完整的工作示例。请注意,必须使用MOCK_METHOD *宏之一声明组件方法更新。要检查参数是否是某种类型的引用,请使用Ref matcher。要使用指针类型绑定到引用,必须取消引用指针,如示例中所示。

此外,了解您必须对实际将要调用的对象设置期望非常重要。我无法判断你的模拟组件是否在你的实体类中的组件容器中,但我在测试中没有设置对注释掉部分中正确对象的期望的问题。

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

class Entity;

class Component
{
public:
   MOCK_METHOD2(update, void(Entity&, uint32_t));
};

class Entity
{
public:
   Entity(Component* c) : c_( c )
   {
   }

   void update(uint32_t dt)
   {
       c_->update(*this, dt);
   }

private:
   Component* c_;
};

using ::testing::Ref;

TEST(MyTest, Component)
{
   Component mockComponent;
   Entity* ea = new Entity( &mockComponent );
   EXPECT_CALL(mockComponent, update(Ref(*ea), 5));
   ea->update( 5 );

   // Component mockComponent2;
   // Entity* ea2 = new Entity( &mockComponent );
   // EXPECT_CALL(mockComponent2, update(Ref(*ea2), 5));
   // ea2->update( 5 );
}

您可能不需要这个,但如果您有cmake,它应该允许您快速构建示例。

cmake_minimum_required(VERSION 3.4)

include(CTest)
include(ExternalProject)

# Add googletest
ExternalProject_Add( googletest
    GIT_REPOSITORY https://github.com/google/googletest.git

    CMAKE_ARGS = "-Dgtest_disable_pthreads=1"

    # Don't run update
    UPDATE_COMMAND ""

    # Disable install step
    INSTALL_COMMAND ""

   # BUILD_BYPRODUCTS googletest-prefix/src/googletest-stamp/googletest-gitinfo.txt
   # BUILD_BYPRODUCTS googletest-prefix/tmp/googletest-cfgcmd.txt
    BUILD_BYPRODUCTS "googletest-prefix/src/googletest-build/googlemock/libgmock_main.a"
    )
# Get include dirs for googletest framework
ExternalProject_Get_Property(googletest source_dir)
set(GTEST_INCLUDE_DIRS
   ${source_dir}/googlemock/include
   ${source_dir}/googletest/include
   )

# Create library target for gmock main, which is used to create
# test executables
ExternalProject_Get_Property(googletest binary_dir)
set(GTEST_LIBRARY_PATH ${binary_dir}/googlemock/libgmock_main.a)
set(GTEST_LIBRARY gmock_main)
add_library(${GTEST_LIBRARY} UNKNOWN IMPORTED)
set_property(TARGET ${GTEST_LIBRARY} PROPERTY IMPORTED_LOCATION ${GTEST_LIBRARY_PATH})
add_dependencies(${GTEST_LIBRARY} googletest)

add_executable(mytest main.cpp)
add_dependencies(mytest googletest)
target_include_directories(mytest BEFORE PRIVATE ${GTEST_INCLUDE_DIRS})
target_link_libraries(mytest gmock_main)

add_test(NAME mytest COMMAND mytest)

如果您运行该示例,它应该为您提供以下输出。

$ ./mytest.exe
Running main() from gmock_main.cc
[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from MyTest
[ RUN      ] MyTest.Component
[       OK ] MyTest.Component (0 ms)
[----------] 1 test from MyTest (0 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran. (0 ms total)
[  PASSED  ] 1 test.

答案 1 :(得分:0)

希望这对您有帮助:

代替:

ea_ = new aronnax::Entity(cla_);
EXPECT_CALL(mockComponent, update(Eq(ByRef(ea_)), testDt)).Times(1);
ea_->update(testDt);

您应将指针转换为引用(在ByRef中注意*):

ea_ = new aronnax::Entity(cla_);
EXPECT_CALL(mockComponent, update(Eq(ByRef(*ea_)), testDt)).Times(1);
ea_->update(testDt);

或简单地在堆栈上定义对象并按原样传递(它将由编译器作为引用传递):

aronnax::Entity ea_(cla_); // NOT a pointer any more
EXPECT_CALL(mockComponent, update(Eq(ByRef(ea_)), testDt)).Times(1);<br>
ea_->update(testDt);