C++ Google mock/unit 测试:未调用模拟方法,原始方法是
C++ Google mock/unit tests : Mock method not called and original one is
我正在模拟一个方法,但我的 GoogleTest
似乎一直在调用原始实现。可能遗漏了什么但找不到这是什么?
我的 class 是一个 Postgres 数据库访问器:
namespace project
{
class PostgresDb
{
public :
// typedef the CursorPtr, this is just a smart pointer.
// sth like
typedef shared_ptr<DbDataType> CursorPtr ;
PostgresDb( const std::string & connString ) ;
CursorPtr getRecords( const int id_1 ,
const int id_2 ) ;
protected :
// this will be used by the MockPostgresDb in our unit tests.
// it leaves the object uninitialized
PostgresDb (){} ;
}
}// end of namespace
这是我的模拟 class:
namespace project_test
{
class MockPostgresDb : public project::PostgresDb
{
public :
MockPostgresDb(){} ;
MOCK_METHOD2( getRecords, CursorPtr*( const int , const int ) ) ;
} ;
class MockCursor : public CursorPtr
{
// ....
}
}
这是我正在测试的方法和测试:
void original_get_method( const int id_1, const int id_2 , PostgresDb db)
{
// ....
db.getRecords( id_1, id_2 ) ;
// ....
}
// helper function
setupGetRecords( MockPostgresDb* db ,
MockCursor* cursor )
{
EXPECT_CALL( *db, getRecords(_,_) )
.Times( 1 )
.WillRepeatedly(::testing::Return( cursor ) ) ;
}
TEST_F(....)
{
MockPostgresDb db ;
MockCursor cursor ;
// ....
setupGetRecords( &db, &cursor ) ;
// ....
// and then calling a functi
original_method( id_1, id_2, db ) ;
}
所以在我看来,我正在调用 original_method
并传递一个 mock_db
。 mock_db
调用其方法 getRecords
,其中 return 是 MockCursor
。这是应该给我模拟的地方,但我确实输入了 db::getRecords
.
我正在尝试查找不匹配的位置,但无法弄清楚。
编辑:
因此,正如指出的那样 - getRecords
应该 return 是 CursorPtr
而不是 CursorPtr*
。所以这就是我所做的:
我也试过改
MOCK_METHOD2( getRecords, CursorPtr*( const int , const int ) ) ;`
到
MOCK_METHOD2( getRecords, CursorPtr( const int , const int ) ) ; // ( no * )
并将助手更改为
// helper function
setupGetRecords( MockPostgresDb* db ,
MockCursor cursor )
{
EXPECT_CALL( *db, getRecords(_,_) )
.Times( 1 )
.WillRepeatedly(::testing::Return( cursor ) ) ;
}
并出现一些类型不匹配的编译错误。什么地方出了错?谢谢。
这里的主要问题是在函数void original_get_method( const int id_1, const int id_2 , PostgresDb db)
中PostgresDb
是按值传递的,即PostgresDb的复制构造函数将被调用。这意味着在 original_get_method
函数内部你没有 MockPostgresDb
-Object 而是一个简单的 PostgresDb
这就是为什么不调用模拟方法而只调用原始实现的原因。此外 getRecords
函数不是虚拟的,即 class MockPostgresDb
中的模拟方法只是隐藏了 PostgresDb
的函数(因此无法告诉程序 运行-时间调用哪个函数,即如果有一个PostgresDb
-对象或对这样一个对象的引用,它将总是调用那个class)中的函数。
首先要改变的是:
class PostgresDb
{
public :
// typedef the CursorPtr, this is just a smart pointer.
// sth like
typedef shared_ptr<DbDataType> CursorPtr ;
PostgresDb( const std::string & connString ) ;
// ===> make this method virtual <====
virtual CursorPtr getRecords( const int id_1 ,
const int id_2 ) ;
}
// pass PostgresDb by reference
void original_get_method( const int id_1, const int id_2 , PostgresDb& db);
这两个更改将调用 original_get_method
中的模拟方法。
下一个问题如评论中指出:
MOCK_METHOD2( getRecords, CursorPtr*( const int , const int ) ) ;
mock 方法具有与基础 class -> 函数不同的签名,不会在派生(模拟)class 中被覆盖(即它们是两个完全不同的函数)。这就是你想要的:
MOCK_METHOD2( getRecords, CursorPtr( const int , const int ) ) ;
下一个问题如下:
typedef shared_ptr<DbDataType> CursorPtr ;
你定义你的新类型CursorPtr
然后继承它
class MockCursor : public CursorPtr {}
但是 MockCursor
不是继承自 DbDataType
,而是继承自 std::shared_ptr
,即它们完全不同。相反,让 MockDbDataType
继承自 DbDataType
并创建一个新类型 MockCursor
:
typedef std::shared_ptr<MockDbDataType> MockCursor;
然后这应该可以正常编译:
setupGetRecords( MockPostgresDb* db ,
MockCursor cursor )
{
EXPECT_CALL( *db, getRecords(_,_) )
.Times( 1 )
.WillRepeatedly(::testing::Return( cursor ) ) ;
}
我还没有测试过这段代码,所以如果有任何问题请告诉我。
我正在模拟一个方法,但我的 GoogleTest
似乎一直在调用原始实现。可能遗漏了什么但找不到这是什么?
我的 class 是一个 Postgres 数据库访问器:
namespace project
{
class PostgresDb
{
public :
// typedef the CursorPtr, this is just a smart pointer.
// sth like
typedef shared_ptr<DbDataType> CursorPtr ;
PostgresDb( const std::string & connString ) ;
CursorPtr getRecords( const int id_1 ,
const int id_2 ) ;
protected :
// this will be used by the MockPostgresDb in our unit tests.
// it leaves the object uninitialized
PostgresDb (){} ;
}
}// end of namespace
这是我的模拟 class:
namespace project_test
{
class MockPostgresDb : public project::PostgresDb
{
public :
MockPostgresDb(){} ;
MOCK_METHOD2( getRecords, CursorPtr*( const int , const int ) ) ;
} ;
class MockCursor : public CursorPtr
{
// ....
}
}
这是我正在测试的方法和测试:
void original_get_method( const int id_1, const int id_2 , PostgresDb db)
{
// ....
db.getRecords( id_1, id_2 ) ;
// ....
}
// helper function
setupGetRecords( MockPostgresDb* db ,
MockCursor* cursor )
{
EXPECT_CALL( *db, getRecords(_,_) )
.Times( 1 )
.WillRepeatedly(::testing::Return( cursor ) ) ;
}
TEST_F(....)
{
MockPostgresDb db ;
MockCursor cursor ;
// ....
setupGetRecords( &db, &cursor ) ;
// ....
// and then calling a functi
original_method( id_1, id_2, db ) ;
}
所以在我看来,我正在调用 original_method
并传递一个 mock_db
。 mock_db
调用其方法 getRecords
,其中 return 是 MockCursor
。这是应该给我模拟的地方,但我确实输入了 db::getRecords
.
我正在尝试查找不匹配的位置,但无法弄清楚。
编辑:
因此,正如指出的那样 - getRecords
应该 return 是 CursorPtr
而不是 CursorPtr*
。所以这就是我所做的:
我也试过改
MOCK_METHOD2( getRecords, CursorPtr*( const int , const int ) ) ;`
到
MOCK_METHOD2( getRecords, CursorPtr( const int , const int ) ) ; // ( no * )
并将助手更改为
// helper function
setupGetRecords( MockPostgresDb* db ,
MockCursor cursor )
{
EXPECT_CALL( *db, getRecords(_,_) )
.Times( 1 )
.WillRepeatedly(::testing::Return( cursor ) ) ;
}
并出现一些类型不匹配的编译错误。什么地方出了错?谢谢。
这里的主要问题是在函数void original_get_method( const int id_1, const int id_2 , PostgresDb db)
中PostgresDb
是按值传递的,即PostgresDb的复制构造函数将被调用。这意味着在 original_get_method
函数内部你没有 MockPostgresDb
-Object 而是一个简单的 PostgresDb
这就是为什么不调用模拟方法而只调用原始实现的原因。此外 getRecords
函数不是虚拟的,即 class MockPostgresDb
中的模拟方法只是隐藏了 PostgresDb
的函数(因此无法告诉程序 运行-时间调用哪个函数,即如果有一个PostgresDb
-对象或对这样一个对象的引用,它将总是调用那个class)中的函数。
首先要改变的是:
class PostgresDb
{
public :
// typedef the CursorPtr, this is just a smart pointer.
// sth like
typedef shared_ptr<DbDataType> CursorPtr ;
PostgresDb( const std::string & connString ) ;
// ===> make this method virtual <====
virtual CursorPtr getRecords( const int id_1 ,
const int id_2 ) ;
}
// pass PostgresDb by reference
void original_get_method( const int id_1, const int id_2 , PostgresDb& db);
这两个更改将调用 original_get_method
中的模拟方法。
下一个问题如评论中指出:
MOCK_METHOD2( getRecords, CursorPtr*( const int , const int ) ) ;
mock 方法具有与基础 class -> 函数不同的签名,不会在派生(模拟)class 中被覆盖(即它们是两个完全不同的函数)。这就是你想要的:
MOCK_METHOD2( getRecords, CursorPtr( const int , const int ) ) ;
下一个问题如下:
typedef shared_ptr<DbDataType> CursorPtr ;
你定义你的新类型CursorPtr
然后继承它
class MockCursor : public CursorPtr {}
但是 MockCursor
不是继承自 DbDataType
,而是继承自 std::shared_ptr
,即它们完全不同。相反,让 MockDbDataType
继承自 DbDataType
并创建一个新类型 MockCursor
:
typedef std::shared_ptr<MockDbDataType> MockCursor;
然后这应该可以正常编译:
setupGetRecords( MockPostgresDb* db ,
MockCursor cursor )
{
EXPECT_CALL( *db, getRecords(_,_) )
.Times( 1 )
.WillRepeatedly(::testing::Return( cursor ) ) ;
}
我还没有测试过这段代码,所以如果有任何问题请告诉我。