【问题标题】:CRTP static polymorphism: is it possible to replace the base class with a mock?CRTP静态多态性:是否可以用mock替换基类?
【发布时间】:2018-01-08 14:54:17
【问题描述】:

我在 websocket 服务器中使用 CRTP 静态多态性来将网络代码与业务逻辑分离。基类调用派生类的方法来处理消息,派生类又调用基类发送/接收。它就像魅力一样,看起来像这样:

template<typename Derived>
class WebsocketSessionBase {
    // basic websocket send/receive stuff

    void someBaseMethod() {
        static_cast<Derived*>(this)->otherDerivedMethod();
    }
};

class WebsocketSession : public WebsocketSessionBase<WebsocketSession> {
    // specific business logic

    void someDerivedMethod() {
        otherBaseMethod();
    }
};

现在是单元测试。由于代码是解耦的,我希望分别在类中测试功能。

测试基类很简单:

class TestSession : public WebsocketSessionBase<TestSession> {
    // same interface as WebsocketSession, but test code, cool!
};

但是如何测试派生类呢?我想到了添加一个 Base 模板参数,这使得测试代码正常(Base 是一个模拟类)。但我最终在生产版本中有 2 个模板类相互引用...... :(

template<typename Base>
class TestableWebsocketSession : public Base {
};

using TestedWebsocketSession = TestableWebsocketSession<MockBase>;
using ProdWebSocketSession = TestableWebsocketSession<WebsocketSessionBase<... // infinite loop - now what!?

这个有可能吗?

【问题讨论】:

    标签: c++ unit-testing crtp static-polymorphism


    【解决方案1】:

    我不知道这是否值得,但您可以将 WebsocketSession 设为采用模板模板参数的类模板:

    template<class T>
    struct WebsocketSessionBase { /*...*/ };
    
    template<template<class> class B>
    struct WebsocketSessionDerived: B<WebsocketSessionDerived<B>>{ /*...*/ };
    
    using WebsocketSession = WebsocketSessionDerived<WebsocketSessionBase>;
    
    using DerivedTestSession = WebsocketSessionDerived<WebsocketSessionMockBase>;
    struct BaseTestSession : WebsocketSessionBase<BaseTestSession>{ /*...*/ };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-07-31
      • 2011-08-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-29
      相关资源
      最近更新 更多