RFC: How to structure xUnit test fixtures that share a chunk of setup + handle mocks that raise events

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

RFC: How to structure xUnit test fixtures that share a chunk of setup + handle mocks that raise events

by Gishu P :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

(Disclaimer: Any resemblance to classes living or dead is purely
coincidental :) Actually this is for a TDD workshop thingie - as a jumpstart
for RhinoMocks..)
My Test subject
public class CrashTestDummy
   {

      string _name;
      IPrinter _printer;
      ILog _logger;
      ... // methods
}

Now I have a test fixture
[TestFixture]
public class Rhino101
   {
      protected readonly string DUMMY_NAME = "IDummy";
      protected readonly int DUMMY_BALANCE = 1010;

      protected MockRepository _mocksRepo;
      protected IBank _mockBank;
      protected IPrinter _mockPrinter;
      protected ILog _mockLogger;
      protected CrashTestDummy _testSubject;

      [SetUp]
      public void BeforeEachTest()
      {
         _mocksRepo = new MockRepository();
         _mockBank = _mocksRepo.StrictMock<IBank>();
         _mockPrinter = _mocksRepo.StrictMock<IPrinter>();
         _mockLogger = _mocksRepo.StrictMock<ILog>();

         _testSubject = new CrashTestDummy(DUMMY_NAME, _mockPrinter,
_mockLogger);
         Console.WriteLine("Base - Setup");
      }
      ... // tests
}

All tests pass - everything's good. Now in one test I need to  verify that
when the Printer raises the Torpedoed event, the Logger logs the event
description. So I add that as a test

[Test]
      public void Test_RaisingAnEventFromAMock()
      {
         var e = new MyEventArgs(DateTime.Now);

         _mockLogger.LogMessage(null);
         LastCall.Constraints(Text.Contains(e.ToString()));
         _mocksRepo.ReplayAll();

         _testSubject.MethodThatDoesTheHookup();
         _mockPrinter.Raise(mockPrinter => mockPrinter.Torpedoed += null,
this, e);
      }

Now I've been using StrictMocks so far - and this test fails because I
didn't set expectations for event subscription (I could but I dont want
to..  seems too intrusive). So my first impulse was to turn just the printer
mock into a dynamic mock (one that responds to unexpected calls silently).
So what we have here is a slight variation on existing setup - "use a
dynamic mock instead of a strict mock for Printer and inject it."
So it looks like a new test fixture (since they dont share setups) - however
I'm not sure how to refactor this to prevent setup duplication.. inheritance
looks easier..

The base class can't have tests or else NUnit adds them too to the test
list. So the base class could just have the instance variables as protected
and the shared setup & teardown . Derived classes override and extend setup
/ teardown and have tests...

Comments ? Also any test patterns related to event-based tests would be
welcome... ( have the xUnit test patterns book but its weight is causing
some reader inertia)


[Non-text portions of this message have been removed]


Re: RFC: How to structure xUnit test fixtures that share a chunk of setup + handle mocks that raise events

by David Tchepak :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Gishu,
I believe the use of strict mocks is pretty much discouraged nowadays for
this very reason.

If you are using Rhino Mocks 3.5+ I recommend using the Arrange - Act -
Assert syntax to give you a dynamic mock without worrying about the
record/replay/verify stuff:

  _mockBank = MockRepository.GenerateMock<IBank>();

Then:

  _mockBank.AssertWasCalled(x => x.SomeMethod());

Or:
  _mockBank.Stub(x => x.SomeMethod()).Returns(something);

More info here:
http://www.davesquared.net/2008/10/very-basics-of-aaa-with-rhino-mocks-35.html
 </shamelessBlogPlug>

Hope this helps,
Regards,
David


On Thu, Sep 24, 2009 at 3:49 PM, Gishu Pillai <gishu.pillai@...>wrote:

>
>
> (Disclaimer: Any resemblance to classes living or dead is purely
> coincidental :) Actually this is for a TDD workshop thingie - as a
> jumpstart
> for RhinoMocks..)
> My Test subject
> public class CrashTestDummy
> {
>
> string _name;
> IPrinter _printer;
> ILog _logger;
> ... // methods
> }
>
> Now I have a test fixture
> [TestFixture]
> public class Rhino101
> {
> protected readonly string DUMMY_NAME = "IDummy";
> protected readonly int DUMMY_BALANCE = 1010;
>
> protected MockRepository _mocksRepo;
> protected IBank _mockBank;
> protected IPrinter _mockPrinter;
> protected ILog _mockLogger;
> protected CrashTestDummy _testSubject;
>
> [SetUp]
> public void BeforeEachTest()
> {
> _mocksRepo = new MockRepository();
> _mockBank = _mocksRepo.StrictMock<IBank>();
> _mockPrinter = _mocksRepo.StrictMock<IPrinter>();
> _mockLogger = _mocksRepo.StrictMock<ILog>();
>
> _testSubject = new CrashTestDummy(DUMMY_NAME, _mockPrinter,
> _mockLogger);
> Console.WriteLine("Base - Setup");
> }
> ... // tests
> }
>
> All tests pass - everything's good. Now in one test I need to verify that
> when the Printer raises the Torpedoed event, the Logger logs the event
> description. So I add that as a test
>
> [Test]
> public void Test_RaisingAnEventFromAMock()
> {
> var e = new MyEventArgs(DateTime.Now);
>
> _mockLogger.LogMessage(null);
> LastCall.Constraints(Text.Contains(e.ToString()));
> _mocksRepo.ReplayAll();
>
> _testSubject.MethodThatDoesTheHookup();
> _mockPrinter.Raise(mockPrinter => mockPrinter.Torpedoed += null,
> this, e);
> }
>
> Now I've been using StrictMocks so far - and this test fails because I
> didn't set expectations for event subscription (I could but I dont want
> to.. seems too intrusive). So my first impulse was to turn just the printer
> mock into a dynamic mock (one that responds to unexpected calls silently).
> So what we have here is a slight variation on existing setup - "use a
> dynamic mock instead of a strict mock for Printer and inject it."
> So it looks like a new test fixture (since they dont share setups) -
> however
> I'm not sure how to refactor this to prevent setup duplication..
> inheritance
> looks easier..
>
> The base class can't have tests or else NUnit adds them too to the test
> list. So the base class could just have the instance variables as protected
> and the shared setup & teardown . Derived classes override and extend setup
> / teardown and have tests...
>
> Comments ? Also any test patterns related to event-based tests would be
> welcome... ( have the xUnit test patterns book but its weight is causing
> some reader inertia)
>
> [Non-text portions of this message have been removed]
>
>  
>


[Non-text portions of this message have been removed]


Re: RFC: How to structure xUnit test fixtures that share a chunk of setup + handle mocks that raise events

by östen petersson :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

only one mock per test, the others should be stubs, since otherwise you are not really testing anything ;)

I would suggest you read "The art of unit testing" by roy osherove...




--- In testdrivendevelopment@..., Gishu Pillai <gishu.pillai@...> wrote:

>
> (Disclaimer: Any resemblance to classes living or dead is purely
> coincidental :) Actually this is for a TDD workshop thingie - as a jumpstart
> for RhinoMocks..)
> My Test subject
> public class CrashTestDummy
>    {
>
>       string _name;
>       IPrinter _printer;
>       ILog _logger;
>       ... // methods
> }
>
> Now I have a test fixture
> [TestFixture]
> public class Rhino101
>    {
>       protected readonly string DUMMY_NAME = "IDummy";
>       protected readonly int DUMMY_BALANCE = 1010;
>
>       protected MockRepository _mocksRepo;
>       protected IBank _mockBank;
>       protected IPrinter _mockPrinter;
>       protected ILog _mockLogger;
>       protected CrashTestDummy _testSubject;
>
>       [SetUp]
>       public void BeforeEachTest()
>       {
>          _mocksRepo = new MockRepository();
>          _mockBank = _mocksRepo.StrictMock<IBank>();
>          _mockPrinter = _mocksRepo.StrictMock<IPrinter>();
>          _mockLogger = _mocksRepo.StrictMock<ILog>();
>
>          _testSubject = new CrashTestDummy(DUMMY_NAME, _mockPrinter,
> _mockLogger);
>          Console.WriteLine("Base - Setup");
>       }
>       ... // tests
> }
>
> All tests pass - everything's good. Now in one test I need to  verify that
> when the Printer raises the Torpedoed event, the Logger logs the event
> description. So I add that as a test
>
> [Test]
>       public void Test_RaisingAnEventFromAMock()
>       {
>          var e = new MyEventArgs(DateTime.Now);
>
>          _mockLogger.LogMessage(null);
>          LastCall.Constraints(Text.Contains(e.ToString()));
>          _mocksRepo.ReplayAll();
>
>          _testSubject.MethodThatDoesTheHookup();
>          _mockPrinter.Raise(mockPrinter => mockPrinter.Torpedoed += null,
> this, e);
>       }
>
> Now I've been using StrictMocks so far - and this test fails because I
> didn't set expectations for event subscription (I could but I dont want
> to..  seems too intrusive). So my first impulse was to turn just the printer
> mock into a dynamic mock (one that responds to unexpected calls silently).
> So what we have here is a slight variation on existing setup - "use a
> dynamic mock instead of a strict mock for Printer and inject it."
> So it looks like a new test fixture (since they dont share setups) - however
> I'm not sure how to refactor this to prevent setup duplication.. inheritance
> looks easier..
>
> The base class can't have tests or else NUnit adds them too to the test
> list. So the base class could just have the instance variables as protected
> and the shared setup & teardown . Derived classes override and extend setup
> / teardown and have tests...
>
> Comments ? Also any test patterns related to event-based tests would be
> welcome... ( have the xUnit test patterns book but its weight is causing
> some reader inertia)
>
>
> [Non-text portions of this message have been removed]
>



Re: RFC: How to structure xUnit test fixtures that share a chunk of setup + handle mocks that raise events

by Gishu P :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Mon, Sep 28, 2009 at 5:32 AM, David Tchepak <tchepak@...> wrote:

>
> If you are using Rhino Mocks 3.5+ I recommend using the Arrange - Act -
> Assert syntax to give you a dynamic mock without worrying about the
> record/replay/verify stuff:
>





Thanks David. The specific issue I was seeing was due to the Record-Replay
model of Rhino Mocks. An event subscription in the test subject's ctor (in
Setup()) was recorded as an expectation - since ReplayAll is only called
half-way thru the test.
Moving to the new v3.5 AAA style resulted in a much more intuitive test.

I guess my bigger question was - how do we share a major chunk of setup code
between 2 test fixtures? Since the setups differ, they should ideally be
different xUnit TestFixtures. However duplicating  the same fixture member
variables and expectations seemed a bit off to me... Was evaluating if
someone had worked out a scheme based on inheritance.

I got another suggestion off the list of having private helper methods that
setup state. So each test begins with a call to one of these setup-helper
methods.

-- Gishu


[Non-text portions of this message have been removed]


Re: Re: RFC: How to structure xUnit test fixtures that share a chunk of setup + handle mocks that raise events

by Gishu P :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Tue, Sep 29, 2009 at 12:01 PM, zzzuperfly <ostenpajobbet@...> wrote:

>
> only one mock per test, the others should be stubs, since otherwise you are not really testing anything ;)
>
> I would suggest you read "The art of unit testing" by roy osherove...
>
Haven't read the book.. interesting guideline though. Wouldn't that
multiply the number of tests ?
e.g. if a single scenario exercises a test subject's interaction with
3 collaborators, wouldn't you have to write 3 tests (alternating which
collaborator gets to be the single mock each time) instead of 1 with
all collaborators as mocks.

Re: Re: RFC: How to structure xUnit test fixtures that share a chunk of setup + handle mocks that raise events

by Steve Freeman-4 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

> only one mock per test, the others should be stubs, since otherwise  
> you are not really testing anything ;)


That's too tight a rule. One concept per test. Or, more usefully, Stub  
Queries, Expect Actions

S

Steve Freeman
http://www.mockobjects.com

Winner of the Agile Alliance Gordon Pask award 2006




Re: RFC: How to structure xUnit test fixtures that share a chunk of setup + handle mocks that raise events

by Steve Freeman-4 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Record/Replay has always been problematic and led to just this kind of  
problem. I don't believe that turning off all the checking is the best  
response either--AAA is only one possible response.

Even so, it strikes me that the broken test is actually telling you  
something useful, that the event subscription is too much for a  
constructor to do.

Factoring out helper methods is often a good technique. For more  
complex setups you should take a look at test data builders.

S.

On 1 Oct 2009, at 12:10, Gishu Pillai wrote:

> On Mon, Sep 28, 2009 at 5:32 AM, David Tchepak <tchepak@...>  
> wrote:
>> If you are using Rhino Mocks 3.5+ I recommend using the Arrange -  
>> Act -
>> Assert syntax to give you a dynamic mock without worrying about the
>> record/replay/verify stuff:
>>
> Thanks David. The specific issue I was seeing was due to the Record-
> Replay
> model of Rhino Mocks. An event subscription in the test subject's  
> ctor (in
> Setup()) was recorded as an expectation - since ReplayAll is only  
> called
> half-way thru the test.
> Moving to the new v3.5 AAA style resulted in a much more intuitive  
> test.
>
> I guess my bigger question was - how do we share a major chunk of  
> setup code
> between 2 test fixtures? Since the setups differ, they should  
> ideally be
> different xUnit TestFixtures. However duplicating  the same fixture  
> member
> variables and expectations seemed a bit off to me... Was evaluating if
> someone had worked out a scheme based on inheritance.
>
> I got another suggestion off the list of having private helper  
> methods that
> setup state. So each test begins with a call to one of these setup-
> helper
> methods.
>
> -- Gishu
>
>
> [Non-text portions of this message have been removed]
>

Steve Freeman
http://www.mockobjects.com

Winner of the Agile Alliance Gordon Pask award 2006




Re: RFC: How to structure xUnit test fixtures that share a chunk of setup + handle mocks that raise events

by franz see :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

+1 on builders!!! :-)

This made my tests more manageable and more readable :-)

On Wed, Nov 11, 2009 at 5:32 AM, Steve Freeman <smgfreeman@...> wrote:

>
>
> Record/Replay has always been problematic and led to just this kind of
> problem. I don't believe that turning off all the checking is the best
> response either--AAA is only one possible response.
>
> Even so, it strikes me that the broken test is actually telling you
> something useful, that the event subscription is too much for a
> constructor to do.
>
> Factoring out helper methods is often a good technique. For more
> complex setups you should take a look at test data builders.
>
> S.
>
>
> On 1 Oct 2009, at 12:10, Gishu Pillai wrote:
> > On Mon, Sep 28, 2009 at 5:32 AM, David Tchepak <tchepak@...<tchepak%40gmail.com>>
>
> > wrote:
> >> If you are using Rhino Mocks 3.5+ I recommend using the Arrange -
> >> Act -
> >> Assert syntax to give you a dynamic mock without worrying about the
> >> record/replay/verify stuff:
> >>
> > Thanks David. The specific issue I was seeing was due to the Record-
> > Replay
> > model of Rhino Mocks. An event subscription in the test subject's
> > ctor (in
> > Setup()) was recorded as an expectation - since ReplayAll is only
> > called
> > half-way thru the test.
> > Moving to the new v3.5 AAA style resulted in a much more intuitive
> > test.
> >
> > I guess my bigger question was - how do we share a major chunk of
> > setup code
> > between 2 test fixtures? Since the setups differ, they should
> > ideally be
> > different xUnit TestFixtures. However duplicating the same fixture
> > member
> > variables and expectations seemed a bit off to me... Was evaluating if
> > someone had worked out a scheme based on inheritance.
> >
> > I got another suggestion off the list of having private helper
> > methods that
> > setup state. So each test begins with a call to one of these setup-
> > helper
> > methods.
> >
> > -- Gishu
> >
> >
> > [Non-text portions of this message have been removed]
> >
>
> Steve Freeman
> http://www.mockobjects.com
>
> Winner of the Agile Alliance Gordon Pask award 2006
>
>  
>



--
Franz Allan Valencia See | Java Software Engineer
franz.see@...
LinkedIn: http://www.linkedin.com/in/franzsee
Twitter: http://www.twitter.com/franz_see


[Non-text portions of this message have been removed]



------------------------------------

Yahoo! Groups Links

<*> To visit your group on the web, go to:
    http://groups.yahoo.com/group/testdrivendevelopment/

<*> Your email settings:
    Individual Email | Traditional

<*> To change settings online go to:
    http://groups.yahoo.com/group/testdrivendevelopment/join
    (Yahoo! ID required)

<*> To change settings via email:
    testdrivendevelopment-digest@...
    testdrivendevelopment-fullfeatured@...

<*> To unsubscribe from this group, send an email to:
    testdrivendevelopment-unsubscribe@...

<*> Your use of Yahoo! Groups is subject to:
    http://docs.yahoo.com/info/terms/