From e5e62644930e8e5c8ae23881f3db23b8b584e835 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Thu, 19 May 2011 23:21:50 +0200 Subject: [PATCH] technique to install a mock service temporarily --- src/lib/test/mockinjector.hpp | 86 +++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/src/lib/test/mockinjector.hpp b/src/lib/test/mockinjector.hpp index dbc47d3ed..cc39ba0bd 100644 --- a/src/lib/test/mockinjector.hpp +++ b/src/lib/test/mockinjector.hpp @@ -27,8 +27,11 @@ #include "lib/singleton-factory.hpp" +#include "lib/meta/duck-detector.hpp" #include +#include +#include namespace lib { @@ -87,5 +90,88 @@ namespace test{ + /** + * Details of creating and accessing mock instances, + * especially for services implemented as Singleton. + */ + namespace mock { + + using boost::enable_if; + using lumiera::Yes_t; + using lumiera::No_t; + + /** + * A Metafunction to find out, if a type in question + * is used as Singleton and especially has been configured + * to inject Mock implementations defined as Subclasses. + */ + template + class is_Singleton_with_MockInjector + { + META_DETECT_NESTED (ServiceInterface); + META_DETECT_FUNCTION(void, injectSubclass, (TY*) const); + + typedef typename MOCK::ServiceInterface ServiceInterface; + + public: + typedef lib::SingletonFactory SingletonFactory; + + enum{ value = HasNested_ServiceInterface::value + && HasFunSig_injectSubclass::value + }; + }; + + + /** + * Policy-Trait: How to access and inject + * a mock service implementation? + */ + template + struct AccessPoint; + + template + struct AccessPoint >::type> + { + typedef typename is_Singleton_with_MockInjector::SingletonFactory ServiceAccessPoint; + + void + activateMock() + { + ServiceAccessPoint().injectSubclass (new MOCK()); + } + void + deactivateMock() + { + ServiceAccessPoint().injectSubclass (0); + } + }; + }//(End) details of injecting the mock implementation + + + + + /** + * Scoped object for installing/deinstalling a mocked service automatically. + * Placing a suitably specialised instance of this template into a local scope + * will inject the corresponding mock installation and remove it when the + * control flow leaves this scope. + */ + template + struct Use4Test + : boost::noncopyable + { + Use4Test() + { + mock::AccessPoint::activateMock(); + } + + ~Use4Test() + { + mock::AccessPoint::deactivateMock(); + } + }; + + + }} // namespace lib::test #endif