gpt4 book ai didi

c++ - 对采用 "traits"模板参数的对象进行单元测试

转载 作者:塔克拉玛干 更新时间:2023-11-03 06:55:19 25 4
gpt4 key购买 nike

我有一个 Visual Studio 2008 C++03 项目,我想在其中对使用公开静态方法(基于策略的设计、策略模式)的特征模板参数的类进行单元测试。我正在使用 Google Test 和 Google Mock 框架。

例如:

/// the class under test
template< typename FooTraits >
class Foo
{
public:
void DoSomething()
{
FooTraits::handle_type h = FooTraits::Open( "Foo" );
/* ... */
FooTraits::Close( h );
};
};

/// a typical traits structure
struct SomeTraits
{
typedef HANDLE handle_type;
static handle_type Open( const char* name ) { /* ... */ };
static void Close( handle_type h ) { /* ... */ };
};

/// mocked traits that I would like to use for testing
struct MockTraits
{
typedef int handle_type;
static MOCK_METHOD1( Open, handle_type( const char* ) );
static MOCK_METHOD1( Close, void( handle_type ) );
};

/// the test function
TEST( FooTest, VerifyDoSomethingWorks )
{
Foo< MockTraits > foo_under_test;

// expect MockTraits::Open is called once
// expect MockTraits::Close is called once with the parameter returned from Open
foo_under_test.DoSomething();
};

显然这不会按原样工作。 Google Mock 无法模拟静态方法,我需要在测试中创建 Mocked 类的实例来设置其行为和期望。

那么使用 Google Test/Google Mock 对接受模板策略的类进行单元测试的正确方法是什么?

最佳答案

你能用非静态方法创建一个类,创建它的全局实例(或在你的特征中静态),并让你的特征类服从它吗?

因此,为了阐明受 Rob 评论启发的想法:

struct FunnyDoodad
{
FunnyDoodad();
~FunnyDoodad();

MOCK_METHOD1( Open, HANDLE( const char* ) );
MOCK_METHOD1( Close, void( handle_type ) );

};

struct FunnyGlobal {
FunnyGlobal() : pimpl() {}
~FunnyGlobal() { delete pimpl; }

// You'd want some protection here rather than just dereferencing.
// it's the whole point. I'd suggest using whatever unit test assertion
// mechanism your framework uses and make it a fatal check.
handle_type Open(char const* name) { return pimpl->Open(name); }
void Close(handle_type h) { pimpl->Close(h); }
private:
FunnyDoodad * pimpl;

friend struct FunnyDoodad;

void register(FunnyDoodad* p) { pimpl = p; }
void deregister() { pimpl = 0; }
};

FunnyGlobal funnyGlobal;

FunnyDoodad::FunnyDoodad() { funnyGlobal.register(this); }
FunnyDoodad::~FunnyDoodad() { funnyGlobal.deregister(); }

struct TestTraits
{
typedef HANDLE handle_type;
static handle_type Open( const char* name ) { return funnyGlobal.Open(name); };
static void Close( handle_type h ) { funnyGlobal.Close(h); };
};

TEST_CASE(blah)
{
FunnyDoodad testDoodad;

...
}

我想上面的内容可以被模板化并几乎变成一个模式......也许吧。

关于c++ - 对采用 "traits"模板参数的对象进行单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10656706/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com