在C#等语言中,即使只有一个“真实”实现,我也经常让类依赖于接口而不是具体的类。这是为了简化单元测试(通过创建模拟)。
使用C ++编程时,我想要最大的性能,并且仍然使用TDD和模拟。有办法实现两者吗?也就是说,要能够在测试时进行模拟,并在生产代码中直接进行具体调用?
如何用C ++实现?
在C#等语言中,即使只有一个“真实”实现,我也经常让类依赖于接口而不是具体的类。这是为了简化单元测试(通过创建模拟)。
使用C ++编程时,我想要最大的性能,并且仍然使用TDD和模拟。有办法实现两者吗?也就是说,要能够在测试时进行模拟,并在生产代码中直接进行具体调用?
如何用C ++实现?
因此,而不是接口和运行时多态性:
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);