Overmocking

One of the most powerful tool available to developers testing a legacy code base is the ability to mock out classes that their code depends on. This is of great importance since our unit tests need to limit the scope, and we do this by trying to limit our dependencies. Through mocking we can exchange one dependency on the infrastructure of our application for an in-memory mock.

Sometimes mocking is overused, and I am not just talking about cases where every objected gets mocked to the point where we’re testing nothing. I am talking about a different issue in mocking. I am talking about where developers put on their mocking blinders when unit testing. It’s an easy thing to do, and I’ve done it plenty of times myself.

Setting Up Our Example

We will start of by defining our example. We will have a method to do some sort of calculation (an ideal and easy testing scenario). It will be a legacy code base, which means that it is untested code and probably hard to test. We’ll start off by making it a private static method and put in a nice dependency that one might try to mock to avoid.

private static decimal CalculateFooOnXyz(Xyz xyzItem, 
decimal calculationParameter1)
{
var numbersInCalculation = Repository.GetNumbers()
.Where(n => n.IsActive);

foreach (Number number in numbersInCalculation)
{
// Some code that executes for each one.
}
}

Now that we have this method, which is scary and really needs some testing we’ll take a look at the simple way of testing it; we will use parameter injection to pass in the dependency since we’re static we not easily able to do any other safe forms of dependency injection. When we do this, we end up with the following code.
 
private static decimal CalculateFooOnXyz(Xyz xyzItem, 
decimal calculationParameter1, IRepository repository)
{
var numbersInCalculation = repository.GetNumbers()
.Where(n => n.IsActive);

foreach (Number number in numbersInCalculation)
{
// Some code that executes for each one.
}
}

This is a pretty simple change. We now mock out the repository and pass in the mock in our test and we tell it instead to return the collection we specify in memory instead of requesting the data from the database.

Why This is Wrong

My first question is, what is the name of the method? CalculateFooOnXyz. Notice that I didn’t say, “GetDataFromTheDatabase”. That’s because we shouldn’t be doing that. It isn’t part of the calculation. The numbers returned from the database are required for calculating, so that means that we should have that object as our dependency instead.

How We Change It

So instead of making the repository our parameter, we should make the collection of numbers our parameter. This way we’re depending on the in-memory collection of CLR objects. This is much less of a dependency, and in is not one that needs to be mocked. By doing this alternative we’re better following the Single Responsibility and Dependency Inversion principles.

Our best code for testing will look like this.

private static decimal CalculateFooOnXyz(Xyz xyzItem, 
decimal calculationParameter1, List<CalcNumbers> numbersInCalculation)
{
foreach (Number number in numbersInCalculation)
{
// Some code that executes for each one.
}
}

Comments? Have a better way of doing it? Did I make a mistake?

Custom Model Binders in ASP.NET MVC

In ASP.NET MVC, our system is built such that the interactions with the user are handled through Actions on our Controllers. We select our actions based on the route the user is using, which is a fancy way of saying that we base it on a pattern found in the URL they’re using. If we were on a page editing an object and we clicked the save button we would be sending the data to a URL somewhat like this one.

 

Notice that in our route that we have specified the name of the object that we’re trying to save. There is a default Model Binder for this in MVC that will take the form data that we’re sending and bind it to a CLR objects for us to use in our action. The standard Edit action on a controller looks like this.

[HttpPost]
public ActionResult Edit(int id, FormCollection collection)
{
try
{
// TODO: Add update logic here

return RedirectToAction("Index");
}
catch
{
return View();
}
}

If we were to flesh some of this out the way it’s set up here, we would have code that looked a bit like this.

[HttpPost]
public ActionResult Edit(int id, FormCollection collection)
{
try
{
Profile profile = _profileRepository.GetProfileById(id);

profile.FavoriteColor = collection["favorite_color"];
profile.FavoriteBoardGame = collection["FavoriteBoardGame"];

_profileRepository.Add(profile);

return RedirectToAction("Index");
}
catch
{
return View();
}
}


What is bad about this is that we are accessing the FormCollection object which is messy and brittle. Once we start testing this code it means that we are going to be repeating code similar to this elsewhere. In our tests we will need to create objects using these magic strings. What this means is that we are now making our code brittle. If we change the string that is required for this we will have to go through our code correcting them. We will also have to find them in our tests or our tests will fail. This is bad. What we should do instead is have these only appear on one place, our model binder. Then all the code we test is using CLR objects that get compile-time checking. To create our Custom Model Binder this is all we need to do is write some code like this.
public class ProfileModelBinder : IModelBinder
{
ProfileRepository _profileRepository = new ProfileRepository();

public object BindModel(ControllerContext controllerContext,
ModelBindingContext bindingContext)
{
int id = (int)controllerContext.RouteData.Values["Id"];
Profile profile = _profileRepository.GetProfileById(id);

profile.FavoriteColor = bindingContext
.ValueProvider
.GetValue("favorite_color")
.ToString();


profile.FavoriteBoardGame = bindingContext
.ValueProvider
.GetValue("FavoriteBoardGame")
.ToString();

return profile;
}
}

 

Notice that we are using the form collection here, but it is limited to this one location. When we test we will just have to pass in the Profile object to our action, which means that we don’t have to worry about these magic strings as much, and we’re also not getting into the situation where our code becomes so brittle that our tests inhibit change. The last thing we need to do is tell MVC that when it is supposed to create a Profile object that it is supposed to use this model binder. To do this, we just need to Add our binder to the collection of binders in the Application_Start method of our GLobal.ascx.cs file. It’s done like this. We say that this binder is for objects of type Profile and give it a binder to use.

ModelBinders.Binders.Add(typeof (Profile), new ProfileModelBinder());

Now we have a model binder that should let us keep the messy code out of our controllers. Now our controller action looks like this.

[HttpPost]
public ActionResult Edit(Profile profile)
{
try
{
_profileRepository.Add(profile);

return RedirectToAction("Index");
}
catch
{
return View();
}
}

That looks a lot cleaner to me, and if there were other things I needed to do during that action, I could do them without all of the ugly binding logic.

July HudsonSC

The Hudson Software Craftsmanship Group will be meeting July 20, 2011 at 6:00 p.m. with people arriving as early as 5:30. As usual, we will be ordering pizza, and some of us will be gathering at Kepner’s Tavern after the event to continue our discussions.

If you haven’t attended HudsonSC yet, I highly recommend the group. We have a fantastic group of software craftsmen who are always trying to improve their skills as developers. If you’re interested, please sign up to let us know you’re attending. We will also not turn people away at the door, so feel free to just show up for the event.

The event is located in downtown Hudson at 102 First Street. When you enter the building, just go to the second floor and turn right. Keep walking straight, and you will arrive in our meeting room.

This month I am going to suggest to the group that we try an AppKata instead of our usual programming exercises. These focus more on real-world scenarios and include changing requirements.

We are very loose with our agenda, so if you want to bring in something to talk about or an activity to do, go for it. In fact, you can show up and suggest topics and ideas for that day’s meeting.

See you there!

Rock Paper Azure Contest Bot Tips

A Rock Paper Scissors tournament is being put on by the Windows Azure team. The competition is a fun challenge designed to be a fun way to compete against other developers for some bragging rights. If bragging rights aren’t enough for you, there are prizes also being given out.

1st: XBox 360 / Kinect bundle
2nd: Kinect
3rd: $50 Gift Card

To join the competition, you just have to download the starting code and set up an Azure account to submit your code. They have detailed instructions on the site. You can use a code to get the Azure account set up for free.

How the Rock Paper Azure Game Works

You might be asking, isn’t Rock Paper Scissors just random? Basically, yes. Against a human opponent there will be trends, but with a computer you can be far more random. There are a couple of adjustments made to the game.

To win the tournament, you have to beat the most number of other bots. Beating a bot means that you play RPS until one player wins at least 1000 points. If there is a tie on a point, then the winner of the next point wins the points for the tie as well. This means that if you can get a few ties in a row and then win, you can win a lot of points.

How do you win ties? They’ve added a new move called “Dynamite” That move beats all of the basic moves: Rock, Paper, and Scissors. You can only throw Dynamite 100 times per match, so use it wisely.

Isn’t the dynamite broken? No. They’ve also added a move called “Water Balloon”, which only beats dynamite. You can use as many Water Balloons as you want, but be careful they’re beaten by all of the standard moves.

Rock Paper Azure Bot Tips

Look at Log Files

When you submit your bot to the Rock Paper Azure competition and view the log file from each match your bot had with each other. It will show each point in the game, what each player did, and who got the point. Make sure you’re checking games you lose to see why you lost and also examine some games that you won. This is important so you can see which decisions you’re making that help you win.

Tell Yourself Why You Made Each Choice

You are able to write to the log yourself. If you decide to use Dynamite or a Water Balloon, print out a log message telling yourself why you did it. Then take a look at the log of a game and see if you made the right or wrong choice and adjust your bot accordingly.

Don’t Throw Too Many Water Balloons

A problem that I’ve seen with a lot of bots is that they throw too many water balloons. If I can make my bot trick yours into throwing Water Balloons, I will. Be careful of these tactics (my bot sometimes uses them).

Tactics to use and watch out for:

  • Use only 99 dynamite, because your opponent’s algorithm will keep throwing water balloons.
  • Have an intentional gap where you don’t use dynamite. If your opponent was trying to predict your dynamites they will throw some water balloons and you will win.
  • Start delaying your dynamite throws if your opponent starts water ballooning you.

Don’t Be Too Predictable

This sounds obvious, but I’ve seen plenty of bots which are not using random move selection, I write code to defuse them specifically. There was one bot which always countered your last move, so if you do the same move twice he beats the second one. I wrote the code to disable him and he only got 1 point against me after that.

Write More Than One Strategy

My bot has more than one strategy. I have Water Balloon strategies and Dynamite Strategies. Essentially, my bot is able to change how it decides on water balloons and how it decides dynamite based on information at runtime. What this lets me do is either change strategies mid game or select certain tactics to face certain opponents. I am able to check the name of the bot I am facing and use the strategy designed to beat them.

Summary

Go give the competition a shot. There are prizes for the next couple of weeks. Go get a free Azure account set up and see how well you do.

NimblePros is Hiring Developers

NimblePros is looking for new team members as passionate about writing great software as we are. We don’t believe in writing crappy code, and our team is always improving in order to write better code. We continually adjust our processes to promote our goals of reducing waste and delivering better software.

I enjoy working with the NimblePros team, because they’re a fun group of individuals working towards the same goals I am.

If you would like to join the NimblePros team, you can contact us directly by emailing careers@nimblepros.com. Please let us know what interests you about joining our team and what you’re really passionate about.

Here are a few tidbits about us:

The NimblePros team was founded by our area’s Microsoft Regional director, Steve Smith.

We believe that board gaming is great way to build a cohesive team.

NimblePros sponsors and its team runs the local Software Craftsmanship group.