How to mock "using" objects

13 views
Skip to first unread message

Sruli Ganor

unread,
Jan 15, 2012, 11:51:39 AM1/15/12
to Rhino.Mocks
Hi,

I'm testing a class PersonManager, which instantiates an object of
type CityManager with 'using'.
I want to mock all the CityManager methods and constructors. I.e. I
want to skip the constructor in 'using', the Save and Move methods
(which are public virtual).
While I can mock the other personmanager methods (e.g.
GetPersonByName), I found no way to mock the CityManager.
I tried also dependency injection and passed a CityManager object in
the PersonManager constructor, but this did not work either, probably
because the Using instantiates a new CityManager object.

Is there any way to do it?

Thanks in advance.


Public class PersonManager
{
public string GetFirstName(string lastName)
{
using (CityManager cityMgr = new CityManager("London"))
{
cityMgr.Move("UK");
cityMgr.Save();
}

GetPersonByName(…);
}
}



[TestMethod]
:
PersonManager personMgr = mocks.Stub<PersonManager>(BAcontext);
SetupResult.For(personMgr.GetPersonByLastName("Miller")).Return(fakePersons[0]);
name = personMgr.GetFirstName("Miller");
Assert.AreEqual(mCity, "Joseph");

Oskar Berggren

unread,
Jan 16, 2012, 3:26:53 AM1/16/12
to rhino...@googlegroups.com
Hi,

This is precisely why "new is considered bad" and why dependency
injection was invented. :)

Btw, if you pass in a CityManager but then don't use it, creating your
own instead, it isn't really dependency injection, is it?

There are other patterns too of course.... Inject a factory of some
sort which is responsible for creating the CityManager on demand, then
mock the factory. Or move the CityManager creation to a virtual
method, and have the test use a TestPersonManager that inherits from
PersonManager and overrides the virtual method. Or get the CityManager
from a static method, the static method will call into a factory,
which it finds in a static property, and which the tests and bootstrap
code can initialize to either a mock provider, or the real thing,
respectively.

Many of these methods come in handy when you try to take control of,
refactor and create tests for a large legacy code base, where you are
limited in how you can change the code. For new code, dependency
injection is often the way to go.


/Oskar


2012/1/15 Sruli Ganor <sr...@netvision.net.il>:

> --
> You received this message because you are subscribed to the Google Groups "Rhino.Mocks" group.
> To post to this group, send email to rhino...@googlegroups.com.
> To unsubscribe from this group, send email to rhinomocks+...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/rhinomocks?hl=en.
>

Sruli Ganor

unread,
Jan 16, 2012, 7:20:32 AM1/16/12
to Rhino.Mocks
Hi Oskar,

Thanks very much for your quick and detailed answer.

I'm trying to see if I can understand and implement your ideas, and
how they fit into our application.

I'll let you know when I have conclusions.

Sruli

Sruli Ganor

unread,
Jan 18, 2012, 8:38:59 AM1/18/12
to Rhino.Mocks
Hi Oskar,

Thanks again. Creating CityManager in a virtual method works fine for
me.

Sruli

Oskar Berggren

unread,
Jan 18, 2012, 9:58:33 AM1/18/12
to rhino...@googlegroups.com
I find the book "Working Effectively with Legacy Code" by Michael
Feathers to be quite enlightening regarding techniques to introduce
unit testing and refactoring in legacy code. And by extension, things
to avoid in new code. :)

/Oskar


2012/1/18 Sruli Ganor <sr...@netvision.net.il>:

Reply all
Reply to author
Forward
0 new messages