我有一个提供课程Foo
的库。我在Foo
课程中使用我自己的一些成员函数扩展FooExtended
。为了在我的单元测试中使用FooExtended
,我必须使它成为可模拟的,因此我创建了一个接口IFoo
,这是我在整个代码库中使用的类型。然后我创建了两个接口实现:
班级FooMock
- 用于单元测试。
班级FooWrapper
- 在实际计划中使用。它主要是FooExtended
的包装器,它作为成员存储的实例。
问题:问题在于FooWrapper
。我不知道如何利用工厂Lib::create_foo()
来创建Foo
库,而且还有my_added_function()
我在FooExtended
中添加的dynamic_cast
。 #include <iostream>
#include <memory>
#include <cassert>
using namespace std;
// What's in this namespace is in a 3rd party lib that I cannot change.
namespace Lib {
class Foo {
public:
virtual ~Foo() {};
int lib_func() {
return 42;
}
};
// Factory
Foo* create_foo() {
return new Foo();
}
} // namespace Lib
/** I want to extend the 3rd party class, and only use
this extended class in my project */
class FooExtended : public Lib::Foo {
public:
float my_added_func() {
return 1.0;
}
};
/** Interface for class Foo, created so that a mock
implementation of `FooExtended` can be created for unit tests. */
class IFoo {
public:
virtual int lib_func() = 0;
virtual float my_added_func() = 0;
};
/** Mock implemenation of IFoo for unit-tests. */
class FooMock : public IFoo() {
// Blah blah
}
/** Non-mock implementation of IFoo. Just a wrapper for the class with the
actual implementation, i.e. FooExtended. */
class FooWrapper : public IFoo {
public:
int lib_func() override {
assert(mFooExt); // This fails because dynamic_cast failed.
return mFooExt->lib_func();
};
float my_added_func() override {
assert(mFooExt); // This fails because dynamic_cast fails.
return mFooExt->my_added_func();
}
private:
unique_ptr<FooExtended> mFooExt {
unique_ptr<FooExtended>(
// This dynamic_cast fails.
dynamic_cast<FooExtended*>(Lib::create_foo()))
};
};
int main() {
unique_ptr<IFoo> foo { unique_ptr<IFoo>(new FooWrapper()) };
assert(foo != nullptr);
cout << "Starting...";
// Exits the program because of the assert inside.
cout << foo->lib_func() << "\n";
cout << foo->my_added_func();
}
失败。
' }{ " : ? > < \ ] [ ' ; / . ,
答案 0 :(得分:1)
如果您不想为调用虚函数付出代价,可以为Foo创建一个包装器并在程序中使用它:
class IFoo {
public:
virtual ~Foo() {};
virtual int lib_func() = 0;
};
class MyFoo : public IFoo {
int lib_func() override { _foo.lib_func(); }
private:
std::unique_ptr<Foo> _foo = create_foo(); // pseudocode
};
现在您可以创建模拟并将其用于IFoo。