T5 IoC Tests and Mock objects

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

T5 IoC Tests and Mock objects

Adriaan Joubert-3
Hi,

We are using T5 IOC in a standalone application and it is great. Most
tests we can implement with a few mock classes and instantiating an
instance of the implementation of a service. There are however cases
where it is easier to use the IOC registry to stitch things together,
but only replace some services with mocks (or a suitably configured
local instance of a service). Ideally I want to use existing AppModule
configuration modules and only extend with a test module.

My problem is how to get the registry to return my mock objects when
asked for a specific service. It feels like a problem that probably
has a simple solution.

When using a standalone test module, I've managed to write mock
instances into static fields in the TestAppModule, and then return
them from ServiceBuilder methods. This works, but is laborious and
very ugly.

I spent some time picking testify apart, which is great to learn from.
However as far as I can see the dependency injector completely ignores
the IOC registry and intervenes by injecting objects from its own
pool. This has the advantage that it can be initialised after the
registry has been started. This is great, but we only use constructor
injection, so I don't think this is going to work for us.

My next thought is to write the test class into a field in my
TestAppModule before starting up the registry. I imagine I can then
use a ServiceOverride configuration method to pick out the mock
objects I want to use, and provide a custom object locator to return
these for specific services.

This is still quite ugly and does not deal with the problem of how to
handle the situation where objects are recreated in a setup method for
every test run.

So I thought I'd ask before spending more time on this. Anybody have any ideas?

Thanks,

Adriaan

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: T5 IoC Tests and Mock objects

Howard Lewis Ship
That's actually a very interesting idea ... I can see implementing
additional methods on RegistryBuilder that would allow you to supply
pre-built (i.e., mock) implementations of various services, for the
express purpose of testing.

On Mon, Nov 2, 2009 at 10:45 AM, Adriaan Joubert <[hidden email]> wrote:

> Hi,
>
> We are using T5 IOC in a standalone application and it is great. Most
> tests we can implement with a few mock classes and instantiating an
> instance of the implementation of a service. There are however cases
> where it is easier to use the IOC registry to stitch things together,
> but only replace some services with mocks (or a suitably configured
> local instance of a service). Ideally I want to use existing AppModule
> configuration modules and only extend with a test module.
>
> My problem is how to get the registry to return my mock objects when
> asked for a specific service. It feels like a problem that probably
> has a simple solution.
>
> When using a standalone test module, I've managed to write mock
> instances into static fields in the TestAppModule, and then return
> them from ServiceBuilder methods. This works, but is laborious and
> very ugly.
>
> I spent some time picking testify apart, which is great to learn from.
> However as far as I can see the dependency injector completely ignores
> the IOC registry and intervenes by injecting objects from its own
> pool. This has the advantage that it can be initialised after the
> registry has been started. This is great, but we only use constructor
> injection, so I don't think this is going to work for us.
>
> My next thought is to write the test class into a field in my
> TestAppModule before starting up the registry. I imagine I can then
> use a ServiceOverride configuration method to pick out the mock
> objects I want to use, and provide a custom object locator to return
> these for specific services.
>
> This is still quite ugly and does not deal with the problem of how to
> handle the situation where objects are recreated in a setup method for
> every test run.
>
> So I thought I'd ask before spending more time on this. Anybody have any ideas?
>
> Thanks,
>
> Adriaan
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [hidden email]
> For additional commands, e-mail: [hidden email]
>
>



--
Howard M. Lewis Ship

Creator of Apache Tapestry

The source for Tapestry training, mentoring and support. Contact me to
learn how I can get you up and productive in Tapestry fast!

(971) 678-5210
http://howardlewisship.com

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: T5 IoC Tests and Mock objects

Adriaan Joubert-3
That would be great! And we would need some way of invalidating a
service so that a clean mock would be picked up for a successive test,
i.e something like the per-test scope in testify? I assume a life
cycle service would do the job, but I think then a way of changing the
scope on an existing binding would be required. Also in testify the
per test life-cycle service is strictly per thread, and I have cases
where multi-threaded behaviour is being tested and it would be wrong
to have the services per thread. So two test life-cycle services or
some serious magic would be needed.

Thanks!

Adriaan

2009/11/2 Howard Lewis Ship <[hidden email]>:

> That's actually a very interesting idea ... I can see implementing
> additional methods on RegistryBuilder that would allow you to supply
> pre-built (i.e., mock) implementations of various services, for the
> express purpose of testing.
>
> On Mon, Nov 2, 2009 at 10:45 AM, Adriaan Joubert <[hidden email]> wrote:
>> Hi,
>>
>> We are using T5 IOC in a standalone application and it is great. Most
>> tests we can implement with a few mock classes and instantiating an
>> instance of the implementation of a service. There are however cases
>> where it is easier to use the IOC registry to stitch things together,
>> but only replace some services with mocks (or a suitably configured
>> local instance of a service). Ideally I want to use existing AppModule
>> configuration modules and only extend with a test module.
>>
>> My problem is how to get the registry to return my mock objects when
>> asked for a specific service. It feels like a problem that probably
>> has a simple solution.
>>
>> When using a standalone test module, I've managed to write mock
>> instances into static fields in the TestAppModule, and then return
>> them from ServiceBuilder methods. This works, but is laborious and
>> very ugly.
>>
>> I spent some time picking testify apart, which is great to learn from.
>> However as far as I can see the dependency injector completely ignores
>> the IOC registry and intervenes by injecting objects from its own
>> pool. This has the advantage that it can be initialised after the
>> registry has been started. This is great, but we only use constructor
>> injection, so I don't think this is going to work for us.
>>
>> My next thought is to write the test class into a field in my
>> TestAppModule before starting up the registry. I imagine I can then
>> use a ServiceOverride configuration method to pick out the mock
>> objects I want to use, and provide a custom object locator to return
>> these for specific services.
>>
>> This is still quite ugly and does not deal with the problem of how to
>> handle the situation where objects are recreated in a setup method for
>> every test run.
>>
>> So I thought I'd ask before spending more time on this. Anybody have any ideas?
>>
>> Thanks,
>>
>> Adriaan
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: [hidden email]
>> For additional commands, e-mail: [hidden email]
>>
>>
>
>
>
> --
> Howard M. Lewis Ship
>
> Creator of Apache Tapestry
>
> The source for Tapestry training, mentoring and support. Contact me to
> learn how I can get you up and productive in Tapestry fast!
>
> (971) 678-5210
> http://howardlewisship.com
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [hidden email]
> For additional commands, e-mail: [hidden email]
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: T5 IoC Tests and Mock objects

Howard Lewis Ship
That's a bit more major surgery, but possible. Document all this in an
issue and we'll see about getting it implemented!

On Mon, Nov 2, 2009 at 12:26 PM, Adriaan Joubert <[hidden email]> wrote:

> That would be great! And we would need some way of invalidating a
> service so that a clean mock would be picked up for a successive test,
> i.e something like the per-test scope in testify? I assume a life
> cycle service would do the job, but I think then a way of changing the
> scope on an existing binding would be required. Also in testify the
> per test life-cycle service is strictly per thread, and I have cases
> where multi-threaded behaviour is being tested and it would be wrong
> to have the services per thread. So two test life-cycle services or
> some serious magic would be needed.
>
> Thanks!
>
> Adriaan
>
> 2009/11/2 Howard Lewis Ship <[hidden email]>:
>> That's actually a very interesting idea ... I can see implementing
>> additional methods on RegistryBuilder that would allow you to supply
>> pre-built (i.e., mock) implementations of various services, for the
>> express purpose of testing.
>>
>> On Mon, Nov 2, 2009 at 10:45 AM, Adriaan Joubert <[hidden email]> wrote:
>>> Hi,
>>>
>>> We are using T5 IOC in a standalone application and it is great. Most
>>> tests we can implement with a few mock classes and instantiating an
>>> instance of the implementation of a service. There are however cases
>>> where it is easier to use the IOC registry to stitch things together,
>>> but only replace some services with mocks (or a suitably configured
>>> local instance of a service). Ideally I want to use existing AppModule
>>> configuration modules and only extend with a test module.
>>>
>>> My problem is how to get the registry to return my mock objects when
>>> asked for a specific service. It feels like a problem that probably
>>> has a simple solution.
>>>
>>> When using a standalone test module, I've managed to write mock
>>> instances into static fields in the TestAppModule, and then return
>>> them from ServiceBuilder methods. This works, but is laborious and
>>> very ugly.
>>>
>>> I spent some time picking testify apart, which is great to learn from.
>>> However as far as I can see the dependency injector completely ignores
>>> the IOC registry and intervenes by injecting objects from its own
>>> pool. This has the advantage that it can be initialised after the
>>> registry has been started. This is great, but we only use constructor
>>> injection, so I don't think this is going to work for us.
>>>
>>> My next thought is to write the test class into a field in my
>>> TestAppModule before starting up the registry. I imagine I can then
>>> use a ServiceOverride configuration method to pick out the mock
>>> objects I want to use, and provide a custom object locator to return
>>> these for specific services.
>>>
>>> This is still quite ugly and does not deal with the problem of how to
>>> handle the situation where objects are recreated in a setup method for
>>> every test run.
>>>
>>> So I thought I'd ask before spending more time on this. Anybody have any ideas?
>>>
>>> Thanks,
>>>
>>> Adriaan
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: [hidden email]
>>> For additional commands, e-mail: [hidden email]
>>>
>>>
>>
>>
>>
>> --
>> Howard M. Lewis Ship
>>
>> Creator of Apache Tapestry
>>
>> The source for Tapestry training, mentoring and support. Contact me to
>> learn how I can get you up and productive in Tapestry fast!
>>
>> (971) 678-5210
>> http://howardlewisship.com
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: [hidden email]
>> For additional commands, e-mail: [hidden email]
>>
>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [hidden email]
> For additional commands, e-mail: [hidden email]
>
>



--
Howard M. Lewis Ship

Creator of Apache Tapestry

The source for Tapestry training, mentoring and support. Contact me to
learn how I can get you up and productive in Tapestry fast!

(971) 678-5210
http://howardlewisship.com

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: T5 IoC Tests and Mock objects

Adriaan Joubert-3
Thanks, Howard. I've put it in as
https://issues.apache.org/jira/browse/TAP5-918. Let me know if there
is something I can do to help.

Thanks,

Adriaan

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: T5 IoC Tests and Mock objects

Paul Field-4
In reply to this post by Adriaan Joubert-3
Funnily enough I was thinking of something very similar for Testify. I was
imagining a "from-tests" scope - which is basically like the per-test
scope except that the service proxies look up their implementations from
the pool of objects populated by the @ForComponents annotations.  (Which
probably means the annotations need a name change to @ForTapestry or
something like that).

The important thing for me is that the same IOC can be used from
test-to-test but with different mock/fake implementations being created
each time. When I was originally playing with testing ideas before
Testify, I had an IOC builder that could plug-in pre-created objects (I
think similar to what Howard is suggesting) but you get an overhead in
recreating the IOC for every test. testify is deliberately designed to
avoid overheads like that so your tests go fast.

Actually, thinking about it, we might want a special RegistryBuilder that
creates *all* services with a special proxy that looks for an override
implementation in some dynamic pool of objects - it returns the override
implementation if it finds it in the pool, otherwise it returns the normal
implementation as defined in the module. That way we can change
implementations dynamically at runtime for any service in any module -
cool 8-)   - This sound too good, so there's probably some implications I
haven't thought of...

BTW Adriann - if you want per-test scope to span threads, I think I can
make that happen. Could you pop an issue into the Testify JIRA to remind
me? ( http://tapestry.formos.com/jira/browse/TESTIFY ) Unfortunately, I
don't have a lot of time at the moment, but I will get round to it
eventually.

 - Paul


Adriaan Joubert <[hidden email]> wrote on 02/11/2009 20:26:19:

> That would be great! And we would need some way of invalidating a
> service so that a clean mock would be picked up for a successive test,
> i.e something like the per-test scope in testify? I assume a life
> cycle service would do the job, but I think then a way of changing the
> scope on an existing binding would be required. Also in testify the
> per test life-cycle service is strictly per thread, and I have cases
> where multi-threaded behaviour is being tested and it would be wrong
> to have the services per thread. So two test life-cycle services or
> some serious magic would be needed.
>
> Thanks!
>
> Adriaan
>
> 2009/11/2 Howard Lewis Ship <[hidden email]>:
> > That's actually a very interesting idea ... I can see implementing
> > additional methods on RegistryBuilder that would allow you to supply
> > pre-built (i.e., mock) implementations of various services, for the
> > express purpose of testing.
> >
> > On Mon, Nov 2, 2009 at 10:45 AM, Adriaan Joubert <adriaan.
> [hidden email]> wrote:
> >> Hi,
> >>
> >> We are using T5 IOC in a standalone application and it is great. Most
> >> tests we can implement with a few mock classes and instantiating an
> >> instance of the implementation of a service. There are however cases
> >> where it is easier to use the IOC registry to stitch things together,
> >> but only replace some services with mocks (or a suitably configured
> >> local instance of a service). Ideally I want to use existing
AppModule

> >> configuration modules and only extend with a test module.
> >>
> >> My problem is how to get the registry to return my mock objects when
> >> asked for a specific service. It feels like a problem that probably
> >> has a simple solution.
> >>
> >> When using a standalone test module, I've managed to write mock
> >> instances into static fields in the TestAppModule, and then return
> >> them from ServiceBuilder methods. This works, but is laborious and
> >> very ugly.
> >>
> >> I spent some time picking testify apart, which is great to learn
from.
> >> However as far as I can see the dependency injector completely
ignores

> >> the IOC registry and intervenes by injecting objects from its own
> >> pool. This has the advantage that it can be initialised after the
> >> registry has been started. This is great, but we only use constructor
> >> injection, so I don't think this is going to work for us.
> >>
> >> My next thought is to write the test class into a field in my
> >> TestAppModule before starting up the registry. I imagine I can then
> >> use a ServiceOverride configuration method to pick out the mock
> >> objects I want to use, and provide a custom object locator to return
> >> these for specific services.
> >>
> >> This is still quite ugly and does not deal with the problem of how to
> >> handle the situation where objects are recreated in a setup method
for
> >> every test run.
> >>
> >> So I thought I'd ask before spending more time on this. Anybody
> have any ideas?
> >>
> >> Thanks,
> >>
> >> Adriaan



---

This e-mail may contain confidential and/or privileged information. If you are not the intended recipient (or have received this e-mail in error) please notify the sender immediately and delete this e-mail. Any unauthorized copying, disclosure or distribution of the material in this e-mail is strictly forbidden.

Please refer to http://www.db.com/en/content/eu_disclosures.htm for additional EU corporate and regulatory disclosures.
Reply | Threaded
Open this post in threaded view
|

Re: T5 IoC Tests and Mock objects

Adriaan Joubert-3
Hi Paul,

thanks a lot for your mail. Not having to rebuild the registry between
tests is indeed a major consideration. I like your idea of a special
proxy that can be 'cleaned' and refreshed from a pool.

I do not need the multi-threaded testing on our web applications right
now. I mainly need it for our fat-client java app where we use
constructor injection. I'm happy to put in an issue for you to track
it if you like, but do not want you to feel obliged to spend time on
it now. If a more comprehensive tapestry wide solution could be built
that should solve this problem as well.

Thanks!

Adriaan

2009/11/3 Paul Field <[hidden email]>:

> Funnily enough I was thinking of something very similar for Testify. I was
> imagining a "from-tests" scope - which is basically like the per-test
> scope except that the service proxies look up their implementations from
> the pool of objects populated by the @ForComponents annotations.  (Which
> probably means the annotations need a name change to @ForTapestry or
> something like that).
>
> The important thing for me is that the same IOC can be used from
> test-to-test but with different mock/fake implementations being created
> each time. When I was originally playing with testing ideas before
> Testify, I had an IOC builder that could plug-in pre-created objects (I
> think similar to what Howard is suggesting) but you get an overhead in
> recreating the IOC for every test. testify is deliberately designed to
> avoid overheads like that so your tests go fast.
>
> Actually, thinking about it, we might want a special RegistryBuilder that
> creates *all* services with a special proxy that looks for an override
> implementation in some dynamic pool of objects - it returns the override
> implementation if it finds it in the pool, otherwise it returns the normal
> implementation as defined in the module. That way we can change
> implementations dynamically at runtime for any service in any module -
> cool 8-)   - This sound too good, so there's probably some implications I
> haven't thought of...
>
> BTW Adriann - if you want per-test scope to span threads, I think I can
> make that happen. Could you pop an issue into the Testify JIRA to remind
> me? ( http://tapestry.formos.com/jira/browse/TESTIFY ) Unfortunately, I
> don't have a lot of time at the moment, but I will get round to it
> eventually.

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: T5 IoC Tests and Mock objects

Patrick Moore-6
Yeah

This is incredible useful. In T4 I set up something similar.  We have a
MockBuilderFactory that inserts a proxy that can be switched between a mock
and the real object. This offers these benefits:

   1. Production configuration is the same as the test configuration. (
   reduces "the tests pass but it breaks in production cases" )
   2. Tests can switch back and forth between the "real" service and the
   mock service.

Would be great if T5 had the same capability!

Patrick Moore
Amplafi
http://amplafi.com
650-207-9792
"Put your front window on your front page"
corp blog : http://amplafi.com/blog
personal blog : http://www.sworddance.com/blog


On Sat, Nov 7, 2009 at 4:57 AM, Adriaan Joubert <[hidden email]>wrote:

> Hi Paul,
>
> thanks a lot for your mail. Not having to rebuild the registry between
> tests is indeed a major consideration. I like your idea of a special
> proxy that can be 'cleaned' and refreshed from a pool.
>
> I do not need the multi-threaded testing on our web applications right
> now. I mainly need it for our fat-client java app where we use
> constructor injection. I'm happy to put in an issue for you to track
> it if you like, but do not want you to feel obliged to spend time on
> it now. If a more comprehensive tapestry wide solution could be built
> that should solve this problem as well.
>
> Thanks!
>
> Adriaan
>
> 2009/11/3 Paul Field <[hidden email]>:
> > Funnily enough I was thinking of something very similar for Testify. I
> was
> > imagining a "from-tests" scope - which is basically like the per-test
> > scope except that the service proxies look up their implementations from
> > the pool of objects populated by the @ForComponents annotations.  (Which
> > probably means the annotations need a name change to @ForTapestry or
> > something like that).
> >
> > The important thing for me is that the same IOC can be used from
> > test-to-test but with different mock/fake implementations being created
> > each time. When I was originally playing with testing ideas before
> > Testify, I had an IOC builder that could plug-in pre-created objects (I
> > think similar to what Howard is suggesting) but you get an overhead in
> > recreating the IOC for every test. testify is deliberately designed to
> > avoid overheads like that so your tests go fast.
> >
> > Actually, thinking about it, we might want a special RegistryBuilder that
> > creates *all* services with a special proxy that looks for an override
> > implementation in some dynamic pool of objects - it returns the override
> > implementation if it finds it in the pool, otherwise it returns the
> normal
> > implementation as defined in the module. That way we can change
> > implementations dynamically at runtime for any service in any module -
> > cool 8-)   - This sound too good, so there's probably some implications I
> > haven't thought of...
> >
> > BTW Adriann - if you want per-test scope to span threads, I think I can
> > make that happen. Could you pop an issue into the Testify JIRA to remind
> > me? ( http://tapestry.formos.com/jira/browse/TESTIFY ) Unfortunately, I
> > don't have a lot of time at the moment, but I will get round to it
> > eventually.
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [hidden email]
> For additional commands, e-mail: [hidden email]
>
>