|
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(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 eventsHi 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 eventsonly 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 eventsOn 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 eventsOn 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> 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 eventsRecord/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+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/ |
| Free embeddable forum powered by Nabble | Forum Help |