How best to use IoC during testing

View: New views
7 Messages — Rating Filter:   Alert me  

How best to use IoC during testing

by digitaldias :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi everyone!

I have googled and searched for information about how to use the
Castle container for testing, but have not found a good solution to my
(mis)understanding of how to use the IoC containers.

I have an AckManager in my project that is able to detect that a new ACK message has arrived. I've roughly set it up so:

public class AckManager : IAckManager
{
   private  static IAckDetector _ackDetector = IoC.Container.Resolve<
IAckDetector >( );
   private static  ITransactionManager _transactionManager =
IoC.Container.Resolve< ITransactionManager >( );
}

etc

The IoC.Container is nothing more than :

public static class IoC
{
  public static WindsorContainer Container  = new WindsorContainer( );
}


We are still in the design phase of our project, so TDD is working
well for us. Most of the test functions that we write end up in some
form of communication with the transaction manager, i.e. if an Ack is
detected, the transaction manager will, in some stage or form perform a log of it.

During my unit tests, I set up all the IoC dependencies for the
Manager that I am testing. All dependencies are resolved to instances
of some mock object.

Now, between test runs, I need to be able to release a mocked instance
of a specific interface in order to use a different mock in the next
unit test. I tried using this syntax, but that didn't do it for me:

IoC.Container.Register( Component.For< IAckDetector >( ).Instance(
detectorMock ).OverWrite( ) );

I have also tried to Release a specific interface only; no luck.
The only thing I've had luck with has been to do a
IoC.Container.Dispose() and then re-register all the mocks for each
test that I am running.

Somehow, I do not believe that I doing the optimal thing, but I have found no reference online to how to do this either...

I am prepared for the notion that I could be completely lost, and that what I am attempting to do is nowhere near what I should be doing, but I'll risk it in favour of getting a better understanding of how YOU rig your tests using IoC.

PS: Projects are all C#, using MSTest as the  test framework.



Re: How best to use IoC during testing

by alberto-40 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

That's the problem of using the container as a Service Locator, your classes
are now coupled to the container. You should instead inject your
dependencies (constructor or porperty injection). Then you wouldn't need to
use the container for your unit tests.

On Wed, Sep 30, 2009 at 8:46 PM, digitaldias <pedrod@...> wrote:

> Hi everyone!
>
> I have googled and searched for information about how to use the
> Castle container for testing, but have not found a good solution to my
> (mis)understanding of how to use the IoC containers.
>
> I have an AckManager in my project that is able to detect that a new ACK
> message has arrived. I've roughly set it up so:
>
> public class AckManager : IAckManager
> {
>   private  static IAckDetector _ackDetector = IoC.Container.Resolve<
> IAckDetector >( );
>   private static  ITransactionManager _transactionManager =
> IoC.Container.Resolve< ITransactionManager >( );
> }
>
> etc
>
> The IoC.Container is nothing more than :
>
> public static class IoC
> {
>  public static WindsorContainer Container  = new WindsorContainer( );
> }
>
>
> We are still in the design phase of our project, so TDD is working
> well for us. Most of the test functions that we write end up in some
> form of communication with the transaction manager, i.e. if an Ack is
> detected, the transaction manager will, in some stage or form perform a log
> of it.
>
> During my unit tests, I set up all the IoC dependencies for the
> Manager that I am testing. All dependencies are resolved to instances
> of some mock object.
>
> Now, between test runs, I need to be able to release a mocked instance
> of a specific interface in order to use a different mock in the next
> unit test. I tried using this syntax, but that didn't do it for me:
>
> IoC.Container.Register( Component.For< IAckDetector >( ).Instance(
> detectorMock ).OverWrite( ) );
>
> I have also tried to Release a specific interface only; no luck.
> The only thing I've had luck with has been to do a
> IoC.Container.Dispose() and then re-register all the mocks for each
> test that I am running.
>
> Somehow, I do not believe that I doing the optimal thing, but I have found
> no reference online to how to do this either...
>
> I am prepared for the notion that I could be completely lost, and that what
> I am attempting to do is nowhere near what I should be doing, but I'll risk
> it in favour of getting a better understanding of how YOU rig your tests
> using IoC.
>
> PS: Projects are all C#, using MSTest as the  test framework.
>
>
>
>
> ------------------------------------
>
> Yahoo! Groups Links
>
>
>
>

Re: How best to use IoC during testing

by digitaldias :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Well, that was my original thought as well, and I may revert to that
design, but in the interest of having my question enlightened:

Is it possible to "un-register" an interface that has already been
registered? I mean, it is still the IoC container's job to set up the
wiring during a test run, and because I may need different mocks with
different setups in one single testclass, the need to do this remains.

There is also an "OverWrite" option for the Instance( ) of
Component.For<>( ) that does not seem to do what I would expect it do
do: To overwrite the instance associated with the interface with the new
instance that I am registering. Unfortunately for me, it does not do
just that :)




--- In altdotnet@..., alberto <alberto.email@...> wrote:
>
> That's the problem of using the container as a Service Locator, your
classes
> are now coupled to the container. You should instead inject your
> dependencies (constructor or porperty injection). Then you wouldn't
need to
> use the container for your unit tests.
>
> On Wed, Sep 30, 2009 at 8:46 PM, digitaldias pedrod@... wrote:
>
> > Hi everyone!
> >
> > I have googled and searched for information about how to use the
> > Castle container for testing, but have not found a good solution to
my
> > (mis)understanding of how to use the IoC containers.
> >
> > I have an AckManager in my project that is able to detect that a new
ACK

> > message has arrived. I've roughly set it up so:
> >
> > public class AckManager : IAckManager
> > {
> >   private  static IAckDetector _ackDetector = IoC.Container.Resolve<
> > IAckDetector >( );
> >   private static  ITransactionManager _transactionManager =
> > IoC.Container.Resolve< ITransactionManager >( );
> > }
> >
> > etc
> >
> > The IoC.Container is nothing more than :
> >
> > public static class IoC
> > {
> >  public static WindsorContainer Container  = new WindsorContainer(
);
> > }
> >
> >
> > We are still in the design phase of our project, so TDD is working
> > well for us. Most of the test functions that we write end up in some
> > form of communication with the transaction manager, i.e. if an Ack
is
> > detected, the transaction manager will, in some stage or form
perform a log
> > of it.
> >
> > During my unit tests, I set up all the IoC dependencies for the
> > Manager that I am testing. All dependencies are resolved to
instances
> > of some mock object.
> >
> > Now, between test runs, I need to be able to release a mocked
instance

> > of a specific interface in order to use a different mock in the next
> > unit test. I tried using this syntax, but that didn't do it for me:
> >
> > IoC.Container.Register( Component.For< IAckDetector >( ).Instance(
> > detectorMock ).OverWrite( ) );
> >
> > I have also tried to Release a specific interface only; no luck.
> > The only thing I've had luck with has been to do a
> > IoC.Container.Dispose() and then re-register all the mocks for each
> > test that I am running.
> >
> > Somehow, I do not believe that I doing the optimal thing, but I have
found
> > no reference online to how to do this either...
> >
> > I am prepared for the notion that I could be completely lost, and
that what
> > I am attempting to do is nowhere near what I should be doing, but
I'll risk
> > it in favour of getting a better understanding of how YOU rig your
tests

> > using IoC.
> >
> > PS: Projects are all C#, using MSTest as the  test framework.
> >
> >
> >
> >
> > ------------------------------------
> >
> > Yahoo! Groups Links
> >
> >
> >
> >
>



Re: How best to use IoC during testing

by JP Toto :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Steve Sanderson does a REAL nice job of going over Windsor, IoC
implementations, and testing in his Pro MVC book
http://apress.com/book/view/9781430210078 I'm working my way through it now.
It's excellent.

(I don't know Steve so hopefully this doesn't sound like shameless pimpin)

On Wed, Sep 30, 2009 at 2:46 PM, digitaldias <pedrod@...> wrote:

>
>
> Hi everyone!
>
> I have googled and searched for information about how to use the
> Castle container for testing, but have not found a good solution to my
> (mis)understanding of how to use the IoC containers.
>
> I have an AckManager in my project that is able to detect that a new ACK
> message has arrived. I've roughly set it up so:
>
> public class AckManager : IAckManager
> {
> private static IAckDetector _ackDetector = IoC.Container.Resolve<
> IAckDetector >( );
> private static ITransactionManager _transactionManager =
> IoC.Container.Resolve< ITransactionManager >( );
> }
>
> etc
>
> The IoC.Container is nothing more than :
>
> public static class IoC
> {
> public static WindsorContainer Container = new WindsorContainer( );
> }
>
> We are still in the design phase of our project, so TDD is working
> well for us. Most of the test functions that we write end up in some
> form of communication with the transaction manager, i.e. if an Ack is
> detected, the transaction manager will, in some stage or form perform a log
> of it.
>
> During my unit tests, I set up all the IoC dependencies for the
> Manager that I am testing. All dependencies are resolved to instances
> of some mock object.
>
> Now, between test runs, I need to be able to release a mocked instance
> of a specific interface in order to use a different mock in the next
> unit test. I tried using this syntax, but that didn't do it for me:
>
> IoC.Container.Register( Component.For< IAckDetector >( ).Instance(
> detectorMock ).OverWrite( ) );
>
> I have also tried to Release a specific interface only; no luck.
> The only thing I've had luck with has been to do a
> IoC.Container.Dispose() and then re-register all the mocks for each
> test that I am running.
>
> Somehow, I do not believe that I doing the optimal thing, but I have found
> no reference online to how to do this either...
>
> I am prepared for the notion that I could be completely lost, and that what
> I am attempting to do is nowhere near what I should be doing, but I'll risk
> it in favour of getting a better understanding of how YOU rig your tests
> using IoC.
>
> PS: Projects are all C#, using MSTest as the test framework.
>
>  
>



--
JP Toto   |   james.p.toto@...

] Business: http://www.cognisit.com
] Personal: http://www.viceclown.com  |  http://twitter.com/jptoto
] Projects: http://www.barcampphilly.org  |  http://phillyalt.net

"To understand recursion, you must first understand recursion."

Re: How best to use IoC during testing

by Dennis Olano :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Ok just to enlightened your question, try

IoC.Container.Kernel.RemoveComponent(typeof(IAckDetector).AssemblyQualifiedName);

Make sure you register the component with a key.

HTH.


--- In altdotnet@..., "digitaldias" <pedrod@...> wrote:

>
> Well, that was my original thought as well, and I may revert to that
> design, but in the interest of having my question enlightened:
>
> Is it possible to "un-register" an interface that has already been
> registered? I mean, it is still the IoC container's job to set up the
> wiring during a test run, and because I may need different mocks with
> different setups in one single testclass, the need to do this remains.
>
> There is also an "OverWrite" option for the Instance( ) of
> Component.For<>( ) that does not seem to do what I would expect it do
> do: To overwrite the instance associated with the interface with the new
> instance that I am registering. Unfortunately for me, it does not do
> just that :)
>
>
>
>
> --- In altdotnet@..., alberto <alberto.email@> wrote:
> >
> > That's the problem of using the container as a Service Locator, your
> classes
> > are now coupled to the container. You should instead inject your
> > dependencies (constructor or porperty injection). Then you wouldn't
> need to
> > use the container for your unit tests.
> >
> > On Wed, Sep 30, 2009 at 8:46 PM, digitaldias pedrod@ wrote:
> >
> > > Hi everyone!
> > >
> > > I have googled and searched for information about how to use the
> > > Castle container for testing, but have not found a good solution to
> my
> > > (mis)understanding of how to use the IoC containers.
> > >
> > > I have an AckManager in my project that is able to detect that a new
> ACK
> > > message has arrived. I've roughly set it up so:
> > >
> > > public class AckManager : IAckManager
> > > {
> > >   private  static IAckDetector _ackDetector = IoC.Container.Resolve<
> > > IAckDetector >( );
> > >   private static  ITransactionManager _transactionManager =
> > > IoC.Container.Resolve< ITransactionManager >( );
> > > }
> > >
> > > etc
> > >
> > > The IoC.Container is nothing more than :
> > >
> > > public static class IoC
> > > {
> > >  public static WindsorContainer Container  = new WindsorContainer(
> );
> > > }
> > >
> > >
> > > We are still in the design phase of our project, so TDD is working
> > > well for us. Most of the test functions that we write end up in some
> > > form of communication with the transaction manager, i.e. if an Ack
> is
> > > detected, the transaction manager will, in some stage or form
> perform a log
> > > of it.
> > >
> > > During my unit tests, I set up all the IoC dependencies for the
> > > Manager that I am testing. All dependencies are resolved to
> instances
> > > of some mock object.
> > >
> > > Now, between test runs, I need to be able to release a mocked
> instance
> > > of a specific interface in order to use a different mock in the next
> > > unit test. I tried using this syntax, but that didn't do it for me:
> > >
> > > IoC.Container.Register( Component.For< IAckDetector >( ).Instance(
> > > detectorMock ).OverWrite( ) );
> > >
> > > I have also tried to Release a specific interface only; no luck.
> > > The only thing I've had luck with has been to do a
> > > IoC.Container.Dispose() and then re-register all the mocks for each
> > > test that I am running.
> > >
> > > Somehow, I do not believe that I doing the optimal thing, but I have
> found
> > > no reference online to how to do this either...
> > >
> > > I am prepared for the notion that I could be completely lost, and
> that what
> > > I am attempting to do is nowhere near what I should be doing, but
> I'll risk
> > > it in favour of getting a better understanding of how YOU rig your
> tests
> > > using IoC.
> > >
> > > PS: Projects are all C#, using MSTest as the  test framework.
> > >
> > >
> > >
> > >
> > > ------------------------------------
> > >
> > > Yahoo! Groups Links
> > >
> > >
> > >
> > >
> >
>



Re: Re: How best to use IoC during testing

by Richard Dingwall :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Thu, Oct 1, 2009 at 8:13 AM, digitaldias <pedrod@...> wrote:
> Is it possible to "un-register" an interface that has already been
> registered? I mean, it is still the IoC container's job to set up the
> wiring during a test run, and because I may need different mocks with
> different setups in one single testclass, the need to do this remains.

If you use common service locator, you can just change
ServiceLocator.Current to use a new empty container.

--
Richard Dingwall
http://richarddingwall.name

(Solved) How best to use IoC during testing

by digitaldias :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

That was it :)

Here's the function I added in my test base class:

protected static void IoC_RegisterMock< T >( Mock<T> mock ) where T : class
{
        if( IoC.Container.Kernel.RemoveComponent( typeof( T ).FullName ) )
                Console.WriteLine( "Successfully released component: " + typeof( T ).FullName );

        IoC.Container.Kernel.AddComponentInstance( typeof( T ).FullName, typeof( T ), mock.Object );
}





--- In altdotnet@..., "dennisolano" <DennisOlano@...> wrote:

>
> Ok just to enlightened your question, try
>
> IoC.Container.Kernel.RemoveComponent(typeof(IAckDetector).AssemblyQualifiedName);
>
> Make sure you register the component with a key.
>
> HTH.
>
>
> --- In altdotnet@..., "digitaldias" <pedrod@> wrote:
> >
> > Well, that was my original thought as well, and I may revert to that
> > design, but in the interest of having my question enlightened:
> >
> > Is it possible to "un-register" an interface that has already been
> > registered? I mean, it is still the IoC container's job to set up the
> > wiring during a test run, and because I may need different mocks with
> > different setups in one single testclass, the need to do this remains.
> >
> > There is also an "OverWrite" option for the Instance( ) of
> > Component.For<>( ) that does not seem to do what I would expect it do
> > do: To overwrite the instance associated with the interface with the new
> > instance that I am registering. Unfortunately for me, it does not do
> > just that :)
> >
> >
> >
> >
> > --- In altdotnet@..., alberto <alberto.email@> wrote:
> > >
> > > That's the problem of using the container as a Service Locator, your
> > classes
> > > are now coupled to the container. You should instead inject your
> > > dependencies (constructor or porperty injection). Then you wouldn't
> > need to
> > > use the container for your unit tests.
> > >
> > > On Wed, Sep 30, 2009 at 8:46 PM, digitaldias pedrod@ wrote:
> > >
> > > > Hi everyone!
> > > >
> > > > I have googled and searched for information about how to use the
> > > > Castle container for testing, but have not found a good solution to
> > my
> > > > (mis)understanding of how to use the IoC containers.
> > > >
> > > > I have an AckManager in my project that is able to detect that a new
> > ACK
> > > > message has arrived. I've roughly set it up so:
> > > >
> > > > public class AckManager : IAckManager
> > > > {
> > > >   private  static IAckDetector _ackDetector = IoC.Container.Resolve<
> > > > IAckDetector >( );
> > > >   private static  ITransactionManager _transactionManager =
> > > > IoC.Container.Resolve< ITransactionManager >( );
> > > > }
> > > >
> > > > etc
> > > >
> > > > The IoC.Container is nothing more than :
> > > >
> > > > public static class IoC
> > > > {
> > > >  public static WindsorContainer Container  = new WindsorContainer(
> > );
> > > > }
> > > >
> > > >
> > > > We are still in the design phase of our project, so TDD is working
> > > > well for us. Most of the test functions that we write end up in some
> > > > form of communication with the transaction manager, i.e. if an Ack
> > is
> > > > detected, the transaction manager will, in some stage or form
> > perform a log
> > > > of it.
> > > >
> > > > During my unit tests, I set up all the IoC dependencies for the
> > > > Manager that I am testing. All dependencies are resolved to
> > instances
> > > > of some mock object.
> > > >
> > > > Now, between test runs, I need to be able to release a mocked
> > instance
> > > > of a specific interface in order to use a different mock in the next
> > > > unit test. I tried using this syntax, but that didn't do it for me:
> > > >
> > > > IoC.Container.Register( Component.For< IAckDetector >( ).Instance(
> > > > detectorMock ).OverWrite( ) );
> > > >
> > > > I have also tried to Release a specific interface only; no luck.
> > > > The only thing I've had luck with has been to do a
> > > > IoC.Container.Dispose() and then re-register all the mocks for each
> > > > test that I am running.
> > > >
> > > > Somehow, I do not believe that I doing the optimal thing, but I have
> > found
> > > > no reference online to how to do this either...
> > > >
> > > > I am prepared for the notion that I could be completely lost, and
> > that what
> > > > I am attempting to do is nowhere near what I should be doing, but
> > I'll risk
> > > > it in favour of getting a better understanding of how YOU rig your
> > tests
> > > > using IoC.
> > > >
> > > > PS: Projects are all C#, using MSTest as the  test framework.
> > > >
> > > >
> > > >
> > > >
> > > > ------------------------------------
> > > >
> > > > Yahoo! Groups Links
> > > >
> > > >
> > > >
> > > >
> > >
> >
>