如何避免在生产中使用vtable查找,并且仍然能够在单元测试中进行广泛的模拟?

在C#等语言中,即使只有一个“真实”实现,我也经常让类依赖于接口而不是具体的类。这是为了简化单元测试(通过创建模拟)。

使用C ++编程时,我想要最大的性能,并且仍然使用TDD和模拟。有办法实现两者吗?也就是说,要能够在测试时进行模拟,并在生产代码中直接进行具体调用?

如何用C ++实现?

wupengtao000 回答:如何避免在生产中使用vtable查找,并且仍然能够在单元测试中进行广泛的模拟?

因此,而不是接口和运行时多态性:

struct IService
{
    virtual ~IService() = 0;
    virtual void foo() = 0;
    // ...
};

class C
{
public:
    explicit C(IService& service) : service(service) {}

    void DoJob() { /*..*/ service.foo(); /*..*/ }
    // ..
private:
     IService& service;
};

生产中:

struct Service : IService
{
    void foo() override;
    // ...
};

Service service;
C c(service);
c.doJob();

测试中

struct ServiceMock : IService
{
    void foo() override;
    // ...
};

ServiceMock service;
C c(service);
c.doJob();

您可以为此使用模板:

// No interface to provide requirement,so document it
// TService must have `foo()`,...
// or wait for C++20 concept
template <typename TService>
class C
{
public:
    explicit C(TService& service) : service(service) {}

    void DoJob() { /*..*/ service.foo(); /*..*/ }
    // ..
private:
     TService& service;
};

调用代码与运行时代码大部分相似: -没有继承权。 -不过,在C ++ 17之前更为冗长。 :/

生产中:

struct Service
{
    void foo();
    // ...
};

Service service;
C c(service); // or before C++17 C<Service> c(service);
c.doJob();

测试中:

struct ServiceMock
{
    void foo();
    // ...
};

ServiceMock service;
C c(service); // or before C++17 C<ServiceMock> c(service);
c.doJob();

但是这种模板比const更具感染力(调用可测试代码也应该是模板)。

在C ++ 17之前,它似乎太冗长了:

OuterService<ServiceA<Service1,Service2>,ServiceB<Service1,Service2>> outer(serviceA,servceB);
// versus
// OuterService outer(serviceA,servceB);

本文链接:https://www.f2er.com/3104633.html

大家都在问