# Saturday, August 30, 2008

Somehow I managed to find myself reading a very long rant on RoR and the RoR community by Zed, the creator of Mongrel.  He picks on lots of people, groups of people, technologies, and companies, but here's some of my favorite parts from his rant.

This is exactly what makes Rails a ghetto. A bunch of half-trained former PHP morons who never bother to sit down and really learn the computer science they were too good to study in college.

You hear that? The #1 money maker for 2008 years will be Rails cleanup. I’m not shitting you, it’s true and so just get over it and make the money.

If anyone had known Rails was that unstable they would have laughed in his face. Think about it further, this means that the creator of Rails in his flagship products could not keep them running for longer than 4 minutes on average. Repeat that to yourself. “He couldn’t keep his own servers running for longer than 4 minutes on average.” Assuming his statements are true (which we may never know) he basically duped us all.

What pisses me off is that I know they’re responsible (ThoughtWorks) for turning Ruby on Rails into the next Visual Basic.

After ThoughtWorks left the most recent project we revamped the team. We got rid of pair programming, cut down the number of tests, started cleaning more and more code out, got rid of their shitty tools, and we all started leaving at 6pm. What happens? We doubled our productivity with fewer people.

First it started on the fringe in start-ups and a few lonely places where it’s having mixed success (mostly due to the poor performance of the Ruby platform). Now it’s getting adopted internally at companies where of course it’ll get fucked up again and die off. After that it’ll move to the government sector where it will languish along with it’s new found buddy COBOL.

Saturday, August 30, 2008 5:51:14 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [1]  | 
# Tuesday, August 26, 2008

One of the topics brought up at the agile beer night was test fragility and how mocking frameworks can be a contributor to test smell.  Actually, I'm the one who brought up the point about mocking frameworks and fragility, but further examination revealed some disparity on the subject, specifically related to replay semantics.

I know that when I first started using a mocking framework I assumed it was best practice to use strict mocks.  I mean, why wouldn't you want to verify everything possible?  Apparently I'm not the only one to think this at one point or another.  I found this blog post by Derik Whittaker stating how he prefers strict mocks, it gets really interesting once you read through the comments.  Scott Bellware made the following comment:

Strict mocks is often a design smell.  It causes tests to express knowledge of an operation's internals, which is a violation of encapsulation of the system under test.

Any large code base that depends on strict mocking by default will suffer from unnecessary productivity loss due to breaking tests that have to be fixed where those tests suffer from inappropriate intimacy.

An API's internals are supposed to be allowed to change independently of its tests.  This is an essential quality of an agile codebase.

Strict mocking by default is a rather extreme stance.  Agile succeeds by finding those places where strictness can be slackened without causing any observable and categorical loss in integrity.  Opting for the strictest possible default runs contrary to this heuristic.

Through years of experience with mocking frameworks have I come to the realization that loose mocks should be your default.  Apparently the creator of Rhino Mocks, Ayende, agrees (emphasis is mine).

As an aside, I am deprecating CreateMock in favor of StrictMock. Using strict mocks by default was a bad design decision on my part.

One of the primary reasons mocks introduce fragility is that they require knowledge of the SUT that goes deeper than the public API.  You often need to know what methods on a collaborator will get called and setup some sensible return values that force your SUT through a particular branch of code. To me that's the very definition of tightly coupled.

So, how do we take advantage of a mocking framework, without making our tests fragile and resistive to change?  Unfortunately there's no way to completely avoid the mock object tax, but we can certainly minimize it.

One of the very first things we can do is setup our mocks in a shared fixture setup method. Sharing mock setup between tests is a great way to reduce the verbosity of each test.  A shared setup method will also setup the SUT with the appropriate mocks.

[SetUp]
public void SetUp()
{
    mocks = new MockRepository();
    userRepository = mocks.DynamicMock<IUserRepository>();
    purchaseService = mocks.DynamicMock<IPurchaseService>();
    sut = new Controller(userRepository, purchaseService);
}

You'll notice that the shared fixture setup I've created is using Rhino Mocks dynamic mocks.  You could instead use an auto mocking container to create the mocks for you to save some keystrokes and repetition.

With loose replay semantics (dynamic mocks in Rhino terminology) any method call during the replay state is accepted and if there is no special handling setup for this method a null or zero is returned. All the expected methods must be called if the object is to pass verification.

Too many times I've been burned by an over specified test using strict mocks.  With strict replay semantics only the methods that were explicitly recorded are accepted as valid. This means that any call that is not expected would cause an exception and fail the test. All the expected methods must be called if the object is to pass verification.  Depending on the mock this could be rather verbose leading to many expectations that have nothing to do with the actual test.

Tests should test only one thing.  You may have multiple assertions or expectations per test, but all of those assertions should have the same goal or theme.  I only want to setup the minimal amount of expectations on a mock that will verify a particular behavior in my SUT, anything more is over specified.  More to the point, keep your tests short and concise.

By using dynamic mocks rather than strict mocks, we are free to ignore the parts of the interaction between the SUT and the mock that we don't care about for our particular test.  We can also use setup result instead of expect if we can verify the interaction using a classicist approach.

[Test]
public void Should_show_cart_empty_message_if_cart_is_empty()
{
    SetupResult.For(purchaseService.GetCart()).Return(new ShoppingCart());
    mocks.ReplayAll();

    sut.ShowCart();

    Assert.AreEqual("You're shopping cart is empty", sut.Flash["warning"]);
}

Here I'm verifying behavior without explicit help of the mock framework, I'm only using the mocking framework to stub in my external dependencies and then verifying the expected behavior using a traditional assertion. 

If it weren't for the external service dependency I probably wouldn't be using a mocking framework here.  Mocking frameworks are most valuable at the edges of your components where things come together with the SUT, like databases, web services, and files.

The normal flow through the controller actually uses the purchase service for more than just grabbing the cart, it also uses it to grab the customer's billing information, but for this particular test I don't care whether the billing details get populated or not.  Here's the simple controller method we're testing:

public void ShowCart()
{
    PropertyBag["customer"] = userRepository.GetCustomerDetails(userID);
    PropertyBag["billing"] = purchaseService.GetBillingInfo(userID);

    ShoppingCart cart = purchaseService.GetCart();
    if (cart.IsEmpty)
    {
        Flash["warning"] = "You're shopping cart is empty";
    }
}

Lets say I now want to verify that the billing information gets populated when ShowCart is called.  Here the tables are turned, I don't really care about the call to GetCart() on the purchaseService.  I really only care that the property bag gets properly populated with billing information.

[Test]
public void Should_show_billing_info()
{
    SetupResult.For(purchaseService.GetBillingInfo(0))
        .IgnoreArguments()
        .Return(new BillingInfo());

    mocks.ReplayAll();

    sut.ShowCart();

    Assert.IsNotNull(sut.PropertyBag["billing"]);
    Assert.IsInstanceOfType(typeof(BillingInfo), sut.PropertyBag["billing"]);
}

Perhaps now we're concerned with populating the correct billing information, because as you might imagine, showing someone else's billing info would be a horrible security flaw.  So lets change our test to verify that using a mock.

[Test]
public void Should_show_billing_info()
{
    sut.CurrentUserID = 5;
    Expect.Call(purchaseService.GetBillingInfo(5))
        .Return(new BillingInfo());

    mocks.ReplayAll();

    sut.ShowCart();

    Assert.IsNotNull(sut.PropertyBag["billing"]);
    Assert.IsInstanceOfType(typeof(BillingInfo), sut.PropertyBag["billing"]);

    mocks.VerifyAll();
}

Just by changing from SetupResult.For to Expect.Call we are now explicitly checking that controller gets its billing information using the correct user ID.  We also added in a VerifyAll call.  Now if the purchaseService.GetBillingInfo method is called with anything other than 5, or not called, the test will fail.

By using dynamic mocks we've verified just enough to see if our SUT works without adding a bunch of noise or unneeded fragility to our tests.

Tuesday, August 26, 2008 6:00:11 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [1]  | 
# Friday, August 01, 2008
Friday, August 01, 2008 5:25:33 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [2]  | 

I finally figured out why my code snippets are all so horribly formatted via RSS, and it has nothing to do with the different source code formatters I've been using and everything to do with dasBlog.  I grabbed the dasBlog source and found the problem is with dasBlog's HTML tidy class, but more importantly I also found in the source how to disable it.  The latest dasBlog source has an option to disable formatting.

image

In the latest version of dasBlog they've added a setting to disable RSS formatting. Notice the setting even mentions "may mess up pre whitespace."  Mess up pre whitespace?  Yeah, no kidding.

At least now I don't have to switch blogging platforms, as the upgrade to dasBlog 2.0 is a whole lot easier.  Here's the dasBlog source code that optionally disables the formatting:

if (siteConfig.HtmlTidyContent == false)
{
    item.Description = "<div>" + PreprocessItemContent(entry.EntryId, entry.Content) + "</div>";
}
else
{
    item.Description = ContentFormatter.FormatContentAsHTML(PreprocessItemContent(entry.EntryId, entry.Content));
}
Friday, August 01, 2008 4:33:31 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  |