0

我在 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!?

有可能克服这个吗?

4

1 回答 1

2

我不知道这是否值得,但您可以将 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>{ /*...*/ };
于 2018-01-08T15:10:58.473 回答