technique to install a mock service temporarily
This commit is contained in:
parent
a207a9f003
commit
e5e6264493
1 changed files with 86 additions and 0 deletions
|
|
@ -27,8 +27,11 @@
|
|||
|
||||
|
||||
#include "lib/singleton-factory.hpp"
|
||||
#include "lib/meta/duck-detector.hpp"
|
||||
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
|
||||
|
||||
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 MOCK>
|
||||
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<ServiceInterface> SingletonFactory;
|
||||
|
||||
enum{ value = HasNested_ServiceInterface<MOCK>::value
|
||||
&& HasFunSig_injectSubclass<SingletonFactory>::value
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Policy-Trait: How to access and inject
|
||||
* a mock service implementation?
|
||||
*/
|
||||
template<class MOCK, class YES =void>
|
||||
struct AccessPoint;
|
||||
|
||||
template<class MOCK>
|
||||
struct AccessPoint<MOCK, typename enable_if< is_Singleton_with_MockInjector<MOCK> >::type>
|
||||
{
|
||||
typedef typename is_Singleton_with_MockInjector<MOCK>::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<class SI>
|
||||
struct Use4Test
|
||||
: boost::noncopyable
|
||||
{
|
||||
Use4Test()
|
||||
{
|
||||
mock::AccessPoint<SI>::activateMock();
|
||||
}
|
||||
|
||||
~Use4Test()
|
||||
{
|
||||
mock::AccessPoint<SI>::deactivateMock();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
}} // namespace lib::test
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in a new issue