October 20, 2007

 Software Development Essential Practices

I was in an interesting discussion last night: what software development practices do you consider essential? 

While opinions varied, I think there was some consensus on a few items.  In my list I also include some tools.  Some of these were mentioned by the group, but consider them my own additions.  Also, I am making this list specific to .NET, but the list applies to just about every language.

Universally agreed Practices

  • Source Control (1)
  • Local Development -- Every developer should have everything on their computer to run the system.  This includes all of the software and all of the source code.
  • Bug Tracking - nuf said.  There are to many tools available to list here.
  • TDD - Test Driven Development.  There was a little bit of back and forth, but the general consensus was that this should be done.
  • ORM - Object-Relational Mapping
    • NHibernate 
    • SubSonic - My person favorite
    • LINQ to SQL - not yet, but I feel this should be on the list.
    • LLBLGen ($) - Not free, but I've heard many good things about it.
    • More
  • Continuous Integration - Simple process that sits on a server and waits for things to get checked into your source control system.  When it sees something new, it gets all of the latest source code, compiles it, and runs all of the unit tests.  If there are any problems anywhere in that process it alerts the users (email, desktop icon, wave red flag, etc). (3)
  • One Step Build - it is unbelievably cool to be able to click one button and have your entire project compile, run all tests, and possibly create an install in one step.  Personally, I do like it, but with the current set of tools this is one of the hardest parts to setup.

Highly thought of but non-essential practices

I'm sure I have missed some tools in the list, but it is the practices that are more important anyway.  But if you put a comment about any tool that I missed I will add it to the list.

(1) Source Safe was notably not in the list.  While I don't like it either, it is better than nothing.  But if your team is greater than 5 people or you have multiple people working on the same project you really should look at one of the other products on the list.

(2) Not a unit testing library, but a Mock Object library.  Pick a unit testing libarary (NUnit, MBUnit, XUnit), then pick a mock object library (Rhino Mocks, TypeMock, NMock) to use with it.

(3) I really need to talk about continuous integration more.  But it is one of those things that leads you down a path.  First you add source control, then you start adhering to separation of concerns, then you start unit testing and mocking more, then you add continuous integration, and then one step builds are all part of the mix.  One best practice leads to another, but they don't make a bit of sense without some of the prior pieces.

(4) If you are a Code Rush person instead of a ReSharper person -- carry on, you are in good company.

($) The cost money - not just beer, but may have free version versions as well.

Labels: , , , , , , , , , , ,

 September 24, 2007

 NMock as compared to RhinoMocks

At a recent developer group meeting I was asked why we were using Rhino Mocks instead of NMock. He also pointed out that NMock had minor api rewrite that made it nicer to use.

My answer was that Rhino Mocks was standardized before I started with my current team, but I would look into NMock. It never hurts to comparison shop.

So to get get started. If you are not familiar with either framework, I suggest looking at their quick start guides:

Rhino Mocks Quick Start
NMock Quick Start

How to mock an object.

NMock:

Mockery mocks = new Mockery();
IMyInterface aMocked = mocks.NewMock<IMyInterface>();
Rhino Mocks

MockRepository mocks = new MockRepository ();
IMyInterface aMocked = mocks.CreateMock<IMyInterface>();

So far so good, no real difference between them. Rhino Mocks has a minor more typing involved, but frankly, I have code templates for all of that anyway.

Which is better: Tie. They both work just fine.

But lets backup a second. What does IMyInterface look like. This is what we are going to work with:

public interface IMyInterface
{
 int MyProperty { get; set; } 
 int Add(int i, int j); 
 void MyMethod(int i, int j); 
 event EventHandler&lt;EventArgs&gt; MyEvent; 
}

Mock libraries create fake objects to send to your real objects. Your real object can call the fake object's methods and properties, but you have to give the Mocked objects their values (this is called setting expectations). First to note: you aren't testing the mocked object, you are testing the object calling the mocked object.
Anyway, if you need more info on where or when to use a mocked object I'm sure Google will have many excellent examples for you.

OK, so now that we have that part set, lets move on.

Set and get a property:

Quick note: this is telling the mocked object to expect the property to be set to a value. We are not actually setting the value. Also, when we get the property, we have to tell the mock library what to return.

NMock
// set the property
Expect.Once.On(aMock).SetProperty("MyProperty").To(1);
// get the property
Expect.Once.On(aMock).GetProperty("MyProperty").Will(Return.Value (1));
RhinoMock
// set the property
aMock.MyProperty = 1;
// get the property
Expect.Call(aMock.MyProperty).Return(1);

OK, both sets of calls are supposed to be equivalent. The first thing to notice is that whatever typing saving we had in the construction of the mock object has not been completely lost. But I still think amount of typing it takes to do something is somewhat shallow, so lets dig deeper into the syntax.

As you can see, in NMock nothing is implied. The properties setter will be called exactly once, and the value will be retrieved exactly once. In Rhino Mocks, that detail is implied. But more troubling with NMock is the reliance on using strings to specify which property is being called. Where as with Rhino Mocks, you are using the mocked interface itself.

So if I change the name of my property on the interface, both tests will fail. But with Rhino Mocks it will fail at build time, NMock will have to wait for run time. Also, if I'm using Find Usages (a feature of ReSharper) to find every place that MyProperty is being used, it will pick up the Rhino Mocks code, but will not pick up the NMock code. To me that is a usability issue.

Rhino Mocks wins.

Next test: Call a function and return a value; call a method

NMock
Expect.Once.On(aMock).Method("Add").With(1,2).Will(Return.Value(3));
Expect.Once.On(aMock).Method("MyMethod").With(1,2);
Rhino Mock
Expect.Call(aMock.Add(1,2)).Return(3);
aMock.MyMethod(1,2);

The nice thing here is that both libraries are consistent in their approach. I still don't like how you have to specify the method names by a string though. Also, the Will(Return.Value()) does not seem natural to me.

But I do have to nock Rhino Mocks on how it does methods a bit. If there is nothing to return, you just call the method. If there is something to return you use the Expect.Call method. This does not seem as consistent as it should.

Rhino Mocks wins.

Handle multiple calls

This is actually kind of interesting. With the NMock api, specifying multiple calls is actually quite natural, where as Rhino mocks seems like a hack. In NMock the Expect function has the following options:

  • Exactly(int count)
  • AtLeastOnce
  • AtLeast(int count)
  • AtMost(int count)
  • Between(int start, int stop)
  • Never

With Rhino mocks there are two ways to do this, but in both cases you use the Repeat object. Remember if you are calling something that doesn't return a value, you don't have to use the Expect object. So Rhino Mocks adds the LastCall method. LastCall modifies the expectations for the last call you made to a mocked object.

But you are using the Repeat object itself. And here is what you get with that:

  • Any()
  • AtLeastOnce()
  • Once()
  • Twice()
  • Times(int count);
  • Time(int min, int max)
  • Never()

First thing I will note between Rhino Mocks Repeat and NMocks Expect is that they are mostly equivalent. I would like the wording of NMocks Between over the Rhino Mocks Times function though. But, Rhino Mocks is missing the AtLeast(int count) function.

So if I wanted to call both methods of my interface at least 2 times, here is what it would look like.

NMock
Expect.AtLeast(2).On(aMock).Method("Add").With(1,2).Will(Return.Value(3));
Expect.AtLeast(2).On(aMock).Method("MyMethod").With(1,2);
Rhino Mocks
Expect.Call(aMock.Add(1,2).Return(3).Repeat.Times(2, int.Max);
aMock.MyMethod(1,2); LastCall.Repeat.Times(2, int.Max);

As much as I love Rhino Mocks, NMock is the winner on the repeating calls front. The syntax makes more sense and is easier to follow than Rhino Mocks. But to fix Rhino Mocks should be hard. Add an AtLeast function and make it possible to use the Expect function on methods with no return values and I think it is there.

But I still don't completely like NMock as either. I don't like it that you have to set the number of times something is being called before you tell the mock library WHAT is being called. I don't thing that helps readability at all.

Winner: NMock.

Raising Events

All of us have this. Small little routines that are only used when an event is raised. So we need a way to mock the event so we can test that code.

NMock
// First read this article: http://becomingagile.blogspot.com/2007/03/raising-events-in-nmock-20.html
// then do this:
MockEvent myEvent = new MockEvnet();
Expect.Once.On(aMock).EventAdd("MyEvent", Is.Anything).Will(MockEvent.Hookup(myEvent));
myEvent.Raise();
Rhino Mocks
aMock.MyEvent += null;
LastCall.IgnoreArguments();
// tell Rhino mocks not to care who is connecting to event
IEventRaiser eventRaiser = LastCall.GetEventRaiser();
eventRaiser.Raise(null, null); // pass in nulls for both sender and args

Can you raise events in NMock: Yes. Is it directly supported: No.
Can you raise events in Rhino Mock: Yes. Is it directly supported: Yes.

Now working with events can be a bit hard. Working with events on a fake object takes a bit of mental yoga to really make sure you understand what is going on as well. I am not overly ecstatic with how Rhino Mocks does events...but it is supported without doing Google searches and writing another class.

Rhino Mocks wins.

Throwing Exceptions

We also have code that catches exceptions. How often do you test that code? You should. Here is how you do it.

NMock
Expect.Once.On(aMock).Method("MyMethod").With(1,2)
.Will(Throw.Exception(new Exception("Hi There"));
Rhino Mocks
Expect.Call(aMock.MyMethod(1,2)).Throw(new Exception("Hi there");

So again, both do the job. But I still like the Rhino Mocks terseness better.

Rhino Mocks wins.

Summary

In the end I will stick with Rhino Mocks. The Method(string methodName) style still just kills it for me because it breaks compile-time checking, and the fact that you can't set method parameters in a type safe way. If I change a something in an interface I want that to break my build -- even in my test code!

Will NMock do the job: yes. But I still think Rhino Mocks does it better.

Labels:

 September 21, 2007

 Rhino Mocks: New syntax

I was browsing though the Rhino Mocks documentation when I found there is an entirely new way to setup a test with mocks.

The old way:

[Test]
public void MyOldTest()
{
// Record your expectations here
Expect.Call(myObject.MyProperty).Return(1);

mocks.ReplayAll();

// do your work here
int i = myObject.MyProperty;

// check you values

mocks.VerifyAll();

Assert.AreEqual(1, i);

}

The new way:

[Test]
public void MyNewTest()
{
// Record your expectations here
using ( mocks.Record() )
{
Expect.Call(myObject.MyProperty).Return(1);
}

// do your work here
int i;
using ( mocks.Playback() )
{
i = myObject.MyProperty;
}

// check you values
Assert.AreEqual(1, i);
}

Now, the most obvious thing about the two code examples is that the new way takes more lines of code. But is that really a valid metric? Not always.

The using statements make a nicer differentiation between the setup and the execution. In the old way, the VerifyAll() method was your differentiator. Sorry, but from four feet back, VerifyAll() just looks like another method. The new way, with the 'with' keyword makes for easier transitions from "what we expect to occur" to "Ok, lets do this thing", and "make sure everything worked as planned."

But wait, there is more!

Now for those of you who think you can NEVER have enough ways to do the same thing, and think that anonymous delegates are the GREATEST THING EVER! There is something for you too.

It is the With statement which gives you a fluent interface (which is all the rage on the blogosphere these days). Anyway, it looks like this:

int i;
With.Mocks(mocoks).Expecting( delegate
{
// Record your expectations here
Expect.Call(myObject.MyProperty).Return(1);
})
.Verify(delegate
{
// do your work here
i = myObject.MyProperty;
}
}
// check you values
Assert.AreEqual(1, i);

Now normally I am all in favor of fluent interfaces. SubSonic, LINQ, and Lambda are all great examples of this. But I worry that the fluent style interface is trying too hard in this case.

That said, sometime soon I'll probably see a use for it and it will be wonderful. But until then.

So now you have seen three ways of doing the same thing with one mocking library. That should be enough to keep everyone busy for a while.

Labels:

 June 14, 2007

 Fake Objects in RhinoMocks

It seems Ayende is keeping busy with Rhino Mocks (aside from blogging 5 times per day). He has now implemented Fake Objects (called a Stub in Rhino Mocks).

First to give some background, there is a difference between a Mocked object and a Fake object.
With Fake Objects, think of a simple class with only properties containing both getters and setters. You can set any property to a value, but the fake object really doesn't care what happens to it. If you set a property to a value, it returns that value until that value is set to something else. I am not sure, but I don't thing you can tell a Fake object function what to return. So if you need that, you should probably use the Mock Object -- read on.

With Mock Objects, they are much more complex beasts. You must warn the Mocked object for every call made to the object, and tell the Mocked Object what to return. One nice thing about Mocked Objects is that functions can be mocked.

Each object, Fake and Mock, has their place in a testing scheme, so it is important to know the difference. If you need simple returns with getters and setters, and don't care if something does or doesn't get called use a Fake Object. Otherwise use a Mock Object.

Anyway, if I have an interface that looks like this:

   1:  public interface IMyObject
   2:  {
   3:        public string MyProperty1 { get; set; }
   4:        public string MyProperty2 { get; set; }
   5:  }

I can create and use a Fake Object for it like this:
   1:  IMyObject o = MockRepository.GenerateStub<imyobject>();
   2:  o.MyProperty1 = "Hi";
   3:  o.MyProperty2 = "There";   
   4:  Assert.AreEqual("Hi", o.MyProperty1);
   5:  Assert.AreEqual("There", o.MyProperty2);
as apposed to creating and using a Mock Object
   1:  MockRepository mock = new MockRepository();
   2:  IMyObject o =  mock.CreateMock<IMyObject>();
   3:  Expect.Call(o.MyProperty1).Return("Hi");
   4:  Expect.Call(o.MyProperty2).Return("There");
   5:  mock.ReplayAll();
   6:  Assert.AreEqual("Hi", o.MyProperty1);
   7:  Assert.AreEqual("There", o.MyProperty1);
   8:  mock.VerifyAll();
As you can see, there is nothing special to using a Fake Object, just set and get the properties like normal. Whereas with Mock Object you have to call Expect.Call for everything that gets touched.

Have fun.

Labels: ,

 May 25, 2007

 Rhino.Mocks Presentation

Here is the presentation that I gave on Rhino.Mocks for the West Michigan Day of .Net. Include the PowerPoint and the sample code.

One note: this is using the Adventure Works Lite database that can be found at CodePlex.

Download and be happy.

RhinoMockDemo.zip

Labels: ,

 May 24, 2007

 ReSharper Unit Test Templates

While I was preparing for my presentation on Rhino.Mocks, I make a couple of nice ReSharper template for creating new unit tests and files with, and without, Rhino.Mocks additions.

So, if you are using Rhino.Mocks and ReSharper, I hope these would be useful to you.

Enjoy.

  • Test Class Template.xml -- File Templates, allows you to create a new test class, one with Rhino.Mocks initialized for NUnit, and one simple unit test class for NUnit.
  • Test Method Templates.xml -- Live Templates, creates new test methods for Rhino.Mocks and and another for standard NUnit.

Labels: , ,

 Back from West Michigan Day of .NET

I'm finally back in Idaho. 4700 miles later (driven on interstate 94).

Anyway, I had a good time in Michigan. I saw my wife's brother get married, visited family, and attended the West Michigan day of .NET. While there I gave a presentation on Rhino.Mocks and it seem well received.

I'm going to give it at least one more time here in Boise, probably at NetDug next month. But we will see how scheduling goes.

Labels: