覆盖C ++中的链接以指向模拟实现

问题描述 投票:0回答:1

我需要使用GoogleMock模拟一些类并更改基类实现,以便它实际创建这个模拟的实例。自动生成基类以及其他一些不需要模拟的类,并且所有类都添加在同一个库中。

需要模拟的类是通过工厂创建的,我打算通过它返回子类。我可以“重新链接”这个新库,它已经实现了已经链接的基类吗?

我希望实现的是从被测单元中获取基类的实例,然后将其转换为模拟的基类。

代码示例:

Original.hpp    
class Base
{
private:
    Base();

public:
    virtual ~Base();
    static std::shared_ptr<Base> createInstance();
}



Original.cpp
#include "Original.hpp"
...
std::shared_ptr<Base> Base::createInstance()
{
    return std::shared_ptr<Base>(new Base());
}
...


Modified.hpp
class Derived : public Base
.....


Modified.cpp    
#include "Original.hpp"
#include "Modified.hpp"
...
std::shared_ptr<Base> Base::createInstance()
{
    return std::shared_ptr<Base>((Base*) new Derived());
}

所以我希望只要在项目的任何地方通过createInstance实例化Base类,而使用Modified.cpp中定义的createInstance来返回Derived类。

c++ linker mocking override
1个回答
1
投票

好吧,我想我或多或少了解。如果库已经编译,则无法更改该静态工厂方法的实现。如果您提供自己的实现并尝试将其与现有的lib链接,您将有多个定义(不允许)。你可以做的是在你的应用程序中添加一个层来负责这个Base对象的创建:

// existing implementation
class Base {
public:
    virtual ~Base();
    static std::shared_ptr<Base> createInstance() {
        return std::shared_ptr<Base>(new Base());
    }

private:
    Base() {};
};

// new layer, part of your production code
class IYourFactory {
public:
    virtual ~IYourFactory() = default;
    virtual std::shared_ptr<Base> createInstance() = 0;
};

// new layer, part of your production code
class ProductionFactory: public IYourFactory {
public:
    ~ProductionFactory() override = default;
    std::shared_ptr<Base> createInstance() override {
        return Base::createInstance();
    }
};

// testing code, you can use GMock to create this class
class MockBase: public Base {
public:
    // it's a hack for Base private default constructor
    MockBase(): Base(*Base::createInstance()) {}
    ~MockBase() override = default;
};

// testing code, you can use GMock to create this class
class MockFactory: public IYourFactory {
    ~MockFactory() override = default;
    std::shared_ptr<Base> createInstance() override {
        return std::make_shared<MockBase>();
    }
};

class YourSystem {
public:
    YourSystem(std::shared_ptr<IYourFactory> factory): factory_(factory) {}
    bool doSomeThings() {
        auto basePtr = factory_->createInstance();
        return true;
    }
private:
    std::shared_ptr<IYourFactory> factory_;
};

当然,如果Base类具有一些虚拟功能,你可以在你的override中使用MockBase,它只会起作用。如果没有,这不是要走的路(你需要为Base提供的方法创建自己的界面)。

确切的解决方案取决于您在系统中的使用方式以及Base的界面。

© www.soinside.com 2019 - 2024. All rights reserved.