I use CRTP static polymorphism in a websocket server to decouple networking code from business logic. The base class calls methods on the derived to process messages, the derived in turn calls the base to send/receive. It works like charm, looks something like this:
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();
}
};
Now comes unit testing. Since the code is decoupled I would like the test functionality in the classes separately.
Testing the base class is simple:
class TestSession : public WebsocketSessionBase<TestSession> {
// same interface as WebsocketSession, but test code, cool!
};
But how do I test derived class? Adding a Base template parameter came to my mind, which makes test code ok (Base is a mock class). But I end up having 2 template classes referring to each other in the production version... :(
template<typename Base>
class TestableWebsocketSession : public Base {
};
using TestedWebsocketSession = TestableWebsocketSession<MockBase>;
using ProdWebSocketSession = TestableWebsocketSession<WebsocketSessionBase<... // infinite loop - now what!?
Is it possible to come over this?
I don't know if it's worth it, but you could make WebsocketSession a class template taking a template template parameter :
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>{ /*...*/ };