DI: draft implementation for testmock support
This commit is contained in:
parent
786f051132
commit
f0c8928301
2 changed files with 168 additions and 15 deletions
140
research/try.cpp
140
research/try.cpp
|
|
@ -182,6 +182,14 @@ class DependInject
|
|||
{
|
||||
using Factory = typename Depend<SRV>::Factory;
|
||||
public:
|
||||
template<class SUB>
|
||||
static void
|
||||
__assert_compatible()
|
||||
{
|
||||
static_assert (std::is_base_of<SRV,SUB>::value,
|
||||
"Installed implementation class must be compatible to the interface.");
|
||||
}
|
||||
|
||||
static void
|
||||
installFactory (Factory&& otherFac)
|
||||
{
|
||||
|
|
@ -193,6 +201,24 @@ class DependInject
|
|||
Depend<SRV>::factory = move (otherFac);
|
||||
}
|
||||
|
||||
static void
|
||||
temporarilyInstallAlternateFactory (SRV*& stashInstance, Factory& stashFac, Factory&& newFac)
|
||||
{
|
||||
ClassLock<SRV> guard;
|
||||
stashFac = move(Depend<SRV>::factory);
|
||||
stashInstance = Depend<SRV>::instance;
|
||||
Depend<SRV>::factory = move(newFac);
|
||||
Depend<SRV>::instance = nullptr;
|
||||
}
|
||||
|
||||
static void
|
||||
restoreOriginalFactory (SRV*& stashInstance, Factory& stashFac)
|
||||
{
|
||||
ClassLock<SRV> guard;
|
||||
Depend<SRV>::factory = move(stashFac);
|
||||
Depend<SRV>::instance = stashInstance;
|
||||
}
|
||||
|
||||
static void
|
||||
disableFactory()
|
||||
{
|
||||
|
|
@ -225,6 +251,7 @@ class DependInject
|
|||
static void
|
||||
useSingleton()
|
||||
{
|
||||
__assert_compatible<SUB>();
|
||||
static InstanceHolder<SUB> singleton;
|
||||
installFactory ([&]()
|
||||
{
|
||||
|
|
@ -243,6 +270,7 @@ class DependInject
|
|||
ServiceInstance()
|
||||
: instance_(new IMP{})
|
||||
{
|
||||
__assert_compatible<IMP>();
|
||||
activateServiceAccess (*instance_);
|
||||
}
|
||||
|
||||
|
|
@ -251,6 +279,10 @@ class DependInject
|
|||
deactivateServiceAccess();
|
||||
}
|
||||
|
||||
ServiceInstance (ServiceInstance&&) = default;
|
||||
ServiceInstance (ServiceInstance const&) = delete;
|
||||
ServiceInstance& operator= (ServiceInstance&&) = delete;
|
||||
|
||||
explicit
|
||||
operator bool() const
|
||||
{
|
||||
|
|
@ -272,13 +304,54 @@ class DependInject
|
|||
}
|
||||
};
|
||||
|
||||
template<class IMP>
|
||||
|
||||
template<class MOC>
|
||||
class Local
|
||||
{
|
||||
std::unique_ptr<MOC> mock_;
|
||||
|
||||
SRV* origInstance_;
|
||||
Factory origFactory_;
|
||||
|
||||
public:
|
||||
Local()
|
||||
{
|
||||
|
||||
__assert_compatible<MOC>();
|
||||
temporarilyInstallAlternateFactory (origInstance_, origFactory_
|
||||
,[this]()
|
||||
{
|
||||
disableFactory();
|
||||
mock_.reset(new MOC{});
|
||||
return mock_.get();
|
||||
});
|
||||
}
|
||||
~Local()
|
||||
{
|
||||
restoreOriginalFactory (origInstance_, origFactory_);
|
||||
}
|
||||
|
||||
Local (Local&&) = default;
|
||||
Local (Local const&) = delete;
|
||||
Local& operator= (Local&&) = delete;
|
||||
|
||||
explicit
|
||||
operator bool() const
|
||||
{
|
||||
return bool(mock_);
|
||||
}
|
||||
|
||||
MOC&
|
||||
operator* () const
|
||||
{
|
||||
ENSURE (mock_);
|
||||
return *mock_;
|
||||
}
|
||||
|
||||
MOC*
|
||||
operator-> () const
|
||||
{
|
||||
ENSURE (mock_);
|
||||
return mock_.get();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
@ -367,6 +440,69 @@ main (int, char**)
|
|||
VERIFY_ERROR (LIFECYCLE, DependInject<Dum>::ServiceInstance<SubDummy>{} );
|
||||
SHOW_EXPR( checksum );
|
||||
|
||||
{
|
||||
DependInject<Dum>::Local<SubDummy> mockDum;
|
||||
DependInject<Dummy<3>>::Local<SubDummy> mockDummy3;
|
||||
CHECK (!mockDum);
|
||||
CHECK (!mockDummy3);
|
||||
SHOW_EXPR( dumm().probe() );
|
||||
CHECK ( mockDum);
|
||||
CHECK (!mockDummy3);
|
||||
SHOW_EXPR( checksum );
|
||||
SHOW_EXPR( mockDum->probe() );
|
||||
SHOW_EXPR( checksum );
|
||||
mockDum->offset = 20;
|
||||
SHOW_EXPR( dumm().probe() );
|
||||
|
||||
VERIFY_ERROR (LIFECYCLE, mockDummy3->probe() );
|
||||
SHOW_EXPR( checksum );
|
||||
SHOW_EXPR( dep3().probe() );
|
||||
SHOW_EXPR( checksum );
|
||||
CHECK ( mockDummy3);
|
||||
SHOW_EXPR( mockDummy3->probe() );
|
||||
SHOW_EXPR( checksum );
|
||||
mockDummy3->offset = 10;
|
||||
SHOW_EXPR( dep3().probe() );
|
||||
mockDum->offset = 50;
|
||||
SHOW_EXPR( dep3().probe() );
|
||||
SHOW_EXPR( dumm().probe() );
|
||||
SHOW_EXPR( checksum );
|
||||
}
|
||||
SHOW_EXPR( checksum );
|
||||
SHOW_EXPR( dumm().probe() );
|
||||
VERIFY_ERROR (LIFECYCLE, dep3().probe() );
|
||||
SHOW_EXPR( checksum );
|
||||
{
|
||||
DependInject<Dummy<3>>::ServiceInstance<SubDummy> service{};
|
||||
SHOW_EXPR( checksum );
|
||||
SHOW_EXPR( dep3().probe() );
|
||||
service->offset = 5;
|
||||
SHOW_EXPR( dep3().probe() );
|
||||
SHOW_EXPR( checksum );
|
||||
{
|
||||
DependInject<Dummy<3>>::Local<SubDummy> mockDummy31;
|
||||
CHECK (!mockDummy31);
|
||||
SHOW_EXPR( checksum );
|
||||
SHOW_EXPR( dep3().probe() );
|
||||
SHOW_EXPR( checksum );
|
||||
mockDummy31->offset = 10;
|
||||
SHOW_EXPR( dep3().probe() );
|
||||
SHOW_EXPR( mockDummy31->probe() );
|
||||
SHOW_EXPR( service->probe() );
|
||||
CHECK (mockDummy31->offset != service->offset);
|
||||
service->offset = 35;
|
||||
SHOW_EXPR( dep3().probe() );
|
||||
SHOW_EXPR( mockDummy31->probe() );
|
||||
SHOW_EXPR( service->probe() );
|
||||
SHOW_EXPR( checksum );
|
||||
}
|
||||
SHOW_EXPR( checksum );
|
||||
SHOW_EXPR( dep3().probe() );
|
||||
SHOW_EXPR( checksum );
|
||||
}
|
||||
SHOW_EXPR( checksum );
|
||||
VERIFY_ERROR (LIFECYCLE, dep3().probe() );
|
||||
SHOW_EXPR( checksum );
|
||||
|
||||
cout << "\n.gulp.\n";
|
||||
|
||||
|
|
|
|||
|
|
@ -26839,21 +26839,38 @@
|
|||
<node CREATED="1521208339124" ID="ID_1092066450" MODIFIED="1521387948246" TEXT="(optional)Closure über konkreten Ctor"/>
|
||||
</node>
|
||||
<node CREATED="1521208261887" ID="ID_384054163" MODIFIED="1521208264827" TEXT="Local">
|
||||
<node CREATED="1521209044203" ID="ID_1994153994" MODIFIED="1521209058181" TEXT="Closure über konkreten Ctor"/>
|
||||
<node CREATED="1521209708336" ID="ID_1870723126" MODIFIED="1521209734757" TEXT="Storage für UnterBla-Instanz bereitstellen"/>
|
||||
<node CREATED="1521209447572" ID="ID_1106858165" MODIFIED="1521209693387" TEXT="bestehenden Service-Zugang aus Depend<Bla> beiseite speichern"/>
|
||||
<node CREATED="1521209547606" ID="ID_1693604174" MODIFIED="1521209881556" TEXT="temporär neuen Service-Zugang in Depend<Bla> installieren, an erzeugte Closure delegierend"/>
|
||||
<node CREATED="1521209759585" ID="ID_267047467" MODIFIED="1521209766124" TEXT="Lebenszyklus-Koppelung">
|
||||
<node CREATED="1521209811802" ID="ID_1712617923" MODIFIED="1521209827180" TEXT="für die UnterBla-Instanz"/>
|
||||
<node CREATED="1521209827775" ID="ID_280216675" MODIFIED="1521209850760" TEXT="für den temporär installierten Service-Zugang"/>
|
||||
<node CREATED="1521209044203" ID="ID_1994153994" MODIFIED="1521409010023" TEXT="(optional)Closure mit speziellen Argumenten "/>
|
||||
<node COLOR="#338800" CREATED="1521209708336" ID="ID_1870723126" MODIFIED="1521411844636" TEXT="Storage für UnterBla-Instanz bereitstellen">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node CREATED="1521208724943" ID="ID_221402501" MODIFIED="1521208881882" TEXT="smart-ptr-artiger Zugriff auf die Service-Impl"/>
|
||||
<node CREATED="1521209904013" ID="ID_1098048607" MODIFIED="1521209918615" TEXT="debug/Kontroll-API">
|
||||
<node CREATED="1521209958014" ID="ID_1638584681" MODIFIED="1521210043546" TEXT="Lebenszustand"/>
|
||||
<node CREATED="1521209945287" ID="ID_42798820" MODIFIED="1521210049471" TEXT="Erzeugen/Zerstören der Instanz">
|
||||
<icon BUILTIN="help"/>
|
||||
<node COLOR="#338800" CREATED="1521209447572" ID="ID_1106858165" MODIFIED="1521411847148" TEXT="bestehenden Service-Zugang aus Depend<Bla> beiseite speichern">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node CREATED="1521210051457" ID="ID_1794637059" MODIFIED="1521210070534" TEXT="explizites Deinstallieren">
|
||||
<node COLOR="#338800" CREATED="1521209547606" ID="ID_1693604174" MODIFIED="1521411853636" TEXT="temporär neuen Service-Zugang in Depend<Bla> installieren, an erzeugte Closure delegierend">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1521209759585" ID="ID_267047467" MODIFIED="1521411859346" TEXT="Lebenszyklus-Koppelung">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#338800" CREATED="1521209811802" ID="ID_1712617923" MODIFIED="1521411860363" TEXT="für die UnterBla-Instanz">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1521209827775" ID="ID_280216675" MODIFIED="1521411861265" TEXT="für den temporär installierten Service-Zugang">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1521208724943" ID="ID_221402501" MODIFIED="1521411863017" TEXT="smart-ptr-artiger Zugriff auf die Service-Impl">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node CREATED="1521209904013" ID="ID_1098048607" MODIFIED="1521411940211" STYLE="fork" TEXT="debug/Kontroll-API">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node COLOR="#338800" CREATED="1521209958014" ID="ID_1638584681" MODIFIED="1521411938195" TEXT="Lebenszustand">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node CREATED="1521209945287" ID="ID_42798820" MODIFIED="1521411938195" TEXT="Erzeugen/Zerstören der Instanz">
|
||||
<icon BUILTIN="button_cancel"/>
|
||||
<node CREATED="1521411917770" ID="ID_50731939" MODIFIED="1521411938195" TEXT="YAGNI"/>
|
||||
</node>
|
||||
<node CREATED="1521210051457" ID="ID_1794637059" MODIFIED="1521411938195" TEXT="explizites Deinstallieren">
|
||||
<icon BUILTIN="button_cancel"/>
|
||||
</node>
|
||||
</node>
|
||||
|
|
|
|||
Loading…
Reference in a new issue