CodeBetter.Com
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @CodeBetter

Jeremy D. Miller -- The Shade Tree Developer

Under the hood and working with .Net, TDD, Software Design, and Agile Stuff

Start with a *correctly* failing test

One of the tenets of test driven development I used to (ok, I still do sometimes) blow off is that you always start with a failing test.  You know the drill -- "red bar, green bar, refactor." 

  1. Write the test for the new little piece of code
  2. Run the test and verify that it fails for the right reason
  3. Implement the code and make the test pass
  4. Wash, rinse, and repeat

The second part of step 2 in that list is pretty important too and it's easy to skip it.  An obvious, unspoken requirement of doing TDD is that your unit test code needs to be correct.  It's not enough to get the red bar (that's easy).  Make sure the unit test is failing correctly before you start writing the real code.  That little sanity check of running the test to see the failure is a good way to quickly validate your unit test. 

For example, I routinely employ NMock to create dynamic mock objects in unit tests.  In your unit tests you're telling NMock which methods should be called in the test by passing in strings and setting up the argument expectations.  When you're using NMock won't get any fancy statement completion or handy compiler errors when you fat finger the name of the methods (NMock2 or Rhino Mocks should alleviate this problem.  More on that someday).  If you just run the unit test first, you can usually spot any kind of problems with the NMock expectations pretty quickly before that gets confused with the real code.  One of my favorite TDD idioms now in .Net is to write the test for a new method, then use ReSharper to generate the method stub to match the signature in the unit test.  Out of the box, ReSharper will generate the method with a single line of code "throw new NotImplementedException()."  When you run the failing test, you just look to see that you're breaking because of the NotImplementedException.  As soon as I see test output like the example below, I know my test setup is functioning and I can go ahead and implement the new method.

		[Test]
		public void CloseViewWhenViewIsDirtyAndUserRespondsOk()
		{
			// Define the expected interaction
			_msgBoxMock.ExpectAndReturn(
				"AskYesNoQuestion", 
				true, 
				Presenter.CLOSE_WARNING_TITLE, 
				Presenter.DIRTY_CLOSE_WARNING);
			
			_viewMock.ExpectAndReturn("IsDirty", true);
			_viewMock.Expect("Close");

			// Perform the unit of work
			_presenter.Close();

			// Verify the interaction
			_msgBoxMock.Verify();
			_viewMock.Verify();
		}

------ Test started: Assembly: SampleCode.dll ------

TestCase 'SampleCode.HumbleDialogBox.PresenterTester.CloseViewWhenViewIsDirtyAndUserRespondsOk' failed: System.NotImplementedException : The method or operation is not implemented.
	c:\documents and settings\jeremy.miller\my documents\visual studio projects\samplecode\humbledialogbox2\presenter.cs(46,0): at SampleCode.HumbleDialogBox.Presenter.Close()
	c:\documents and settings\jeremy.miller\my documents\visual studio projects\samplecode\humbledialogbox2\presenter.cs(109,0): at SampleCode.HumbleDialogBox.PresenterTester.CloseViewWhenViewIsDirtyAndUserRespondsOk()


0 succeeded, 1 failed, 0 skipped, took 0.03 seconds.



---------------------- Done ----------------------

 



Comments

Rob Caron's Blog - A Team System Nexus said:

Cleaning-out my “To Blog” file again…
Architects

Handling data in service oriented systemsEdward...
# August 1, 2005 2:58 AM

Leave a Comment

(required)  
(optional)
(required)  

Enter the numbers above:
Add

About Jeremy D. Miller

Jeremy began his IT career writing "Shadow IT" applications to automate his engineering documentation, then wandered into software development because it looked like more fun. Jeremy previously worked as a systems architect building mission critical supply chain software for a Fortune 100 company and learned agile development practices as a .Net consultant at ThoughtWorks, one of the pioneers of agile development. Jeremy is the author of the open source StructureMap (http://structuremap.sourceforge.net) tool for Dependency Injection with .Net and the forthcoming StoryTeller (http://storyteller.tigris.org) tool for supercharged FIT testing in .Net. Jeremy's thoughts on just about everything software related can be found on his weblog "The Shade Tree Developer" at http://codebetter.com/blogs/jeremy.miller, part of the popular CodeBetter site. Jeremy is a Microsoft MVP for C#. Check out Devlicio.us!

Our Sponsors

This Blog

Syndication

News

All opinions expressed here constitute my (Jeremy D. Miller's) personal opinion, and do not necessarily represent the opinion of any other organization or person, including (but not limited to) my fellow employees, my employer, its clients or their agents.

About Me

"Best Of" Compendium

StructureMap (Dependency Injection for .Net)

StoryTeller (Supercharged Fit)

Build your own Cab

TestDriven

MVP