Class 单元测试用例模拟所需的更改

Class changes required for mocking for Unit Test Cases

我们有一个 class 具有实现线程的方法:

class ThreadPool
{
//Thread creation and invocation
int Create();
};

另一个class,其中嵌入了一个ThreadPool

class Service
{
public:
ThreadPool mThreadPool;
int start();
}

int Service::start()
{
mThreadPoll.Create();
.......
}

上述设计模式的原因我无法模拟我的服务class。

我正在尝试编写一个接口 class 到 ThreadPool 并在服务中使用它 class:

class InterfaceThreadPool
{
virtual int Create () = 0;
};

class ThreadPool : public InterfaceThreadPool
{
int Create () override;
};

我的想法是创建一个接口 class ThreadPoolImpl,我可以在我的服务中使用它 Class:

class Service : public ThreadPoolImpl  
{
public:
int start();
}
int Service::start()
{
Create(); // as inherited from ThreadPoolImpl  
.......
}

好处是现在我可以模拟我的服务class。但是我无法定义 ThreadPoolImpl class

class ThreadPoolImpl : public InterfaceThreadPool
{
int Create () override;
}
int ThreadPoolImpl::Create()
{
//how can I call ThreadPool Create
}

我实际上不同意@Jarod42 的评论。如果你想测试和模拟你的 ThreadPool class 和 Service class,舒适的方法是像这样设计它:

class InterfaceThreadPool
{
public:
    virtual ~InterfaceThreadPool() = default;
    virtual int Create () = 0;
};

class ThreadPool : public InterfaceThreadPool
{
public:
    ~ThreadPool() override;
    int Create () override;
};

class IService
{
public:
    virtual ~IService() = default;
    virtual int start() = 0;
};

class Service: public IService
{
public:
    /*
     * InterfaceThreadPool might be passed by raw ptr, reference, smart ptr, whataver you like the most
     */
    Service(InterfaceThreadPool* mThreadPool);
    ~Service() override;
    int start() override { return mThreadPool_->Create(); }
private:
    InterfaceThreadPool* mThreadPool_;
};

然后在您的生产代码中使用 ServiceThreadPool 的适当实现。在你的测试中你可以使用:

  • MockThreadPool(源自InterfaceThreadPool)测试Service
  • MockThreadPool + MockService(源自 IService)来测试需要这两个 classes
  • 的其他一些东西
  • MockService + ThreadPool 在调用 start 函数时调用的实现(这不是很常见,但也许你会发现它有用)