我正在尝试使用模拟来测试使用某些参数调用某个方法,并且在测试*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}}进行比较。
答案 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);