Microsoft versus Open Source Software - ALT.NET notes

Tuesday, April 22, 2008 by scott
4 comments

At the Seattle alt.net conference, I co-sponsored a session with Justin Angel. The topic was "Choosing Microsoft versus Mature Open Source Alternatives". We wanted to hear the rationale people were using when making choices, like:

LINQ to SQL or Castle Active Record

Entity Framework or NHibernate

Subversion and assorted tools or Team Foundation Server

Not once do I remember price being a factor. Most of the fishbowl conversation revolved around risk. There are risks that technical people don't like, and risks that business people don't like. I tried to take all the major topics mentioned and fit them into the following table.


Choose Microsoft

Choose OSS

Business Risks


License issues

Lack of formal support

Hard to hire experts

Technical Risks

V1 and V2 won't always work

Waiting on bug fixes

Friction

Small communities

Lack of training material

Quick summary - Microsoft is a safe choice from the business perspective, but MSFT products can create an uphill struggle for developers. Brad Abrams and ScottGu both popped into the fishbowl to talk about Microsoft's change of direction in building closed source frameworks with "big bang" releases. ScottGu also reminded us that patent trolls create problems for everyone in the ecosystem.

ALT.NET Trivia

How much ALT.NET can you fit in a Hyundai?

According to Hertz, the Hyundai Elantra will accommodate 5 people and 3 pieces of luggage.

The Elantra I drove into Redmond accommodated 5 people (me, Jeremy Miller, Udi Dahan, Steven "I Love The Back Middle Seat" Harman, and Ayende), 6 pieces of luggage, and 3, maybe 4 laptop bags. It was tight. 

Who said developers can't optimize for space anymore?

A Gentle Introduction to Mocking

Thursday, April 17, 2008 by scott
1 comment

At the last CMAP Code Camp I did a "code-only" presentation entitled "A Gentle Introduction to Mocking". We wrote down some requirements, opened Visual Studio, and started writing unit tests. Matt Podwysocki provided color commentary. Code download is here.

I started "accepting" mock objects as one tool in my unit testing toolbox about three years ago (see "The 5 Stages Of Mocking"). Times have changed quite a bit since then, and the tools have improved dramatically. During the presentation we used the following:

Rhino Mocks – the first mocking framework used in the presentation. Years ago, Oren and Rhino Mocks saved us from "string based" mock objects. Rhino Mocks can easily conjure up a strongly typed mock object. The strong typing results in fewer errors, and greatly enhances the refactoring experience.

moq – is the latest mocking framework in the .NET space and is authored by kzu and friends. moq uses lambda expressions and expression trees to define mock object behavior, and also provides strongly typed mocks. The recent addition of factories and mock verification means you can do traditional interaction style testing with moq, if that is the path you choose. The primary differentiator between the two frameworks is that moq does not use a record / playback paradigm.

Here is a test we wrote with Rhino Mocks:

[Fact]
public void Does_Not_Make_Deposit_When_Verification_Fails()
{
    
MockRepository mocks = new MockRepository();
    
IAuditService auditService = mocks.DynamicMock<IAuditService>();
    
IVerificationService verificationService = mocks.CreateMock<IVerificationService>();

    
decimal amount = 1000;
    
BankAccount account = new BankAccount(auditService,
                                          verificationService);

    
using (mocks.Record())
    {
        
Expect.Call(verificationService.VerifyDeposit(account, amount))
              .Return(
false);

    }

    
using (mocks.Playback())
    {
        account.Deposit(amount);
    }

    account.Balance.ShouldEqual(0);

}

The same test using moq:

[Fact]
public void Does_Not_Make_Deposit_When_Verification_Fails()
{
    
Mock<IAuditService> _auditMock = new Mock<IAuditService>();
    
Mock<IVerificationService> _verificationMock = new Mock<IVerificationService>();

    
decimal amount = 1000;
    
BankAccount account = new BankAccount(_auditMock.Object, _verificationMock.Object);


    _auditMock.Expect(a => a.WriteMessage(
It.IsAny<string>()));
    _verificationMock.Expect(v => v.VerifyDeposit(account, amount))
                     .Returns(
false);

    account.Deposit(amount);
    account.Balance.ShouldEqual(0);            
}

xUnit.net – although not featured in the presentation, xUnit.net drove all the unit tests. xUnit is a new framework authored by Jim Newkirk and Brad Wilson. The framework codifies some unit testing best practices and takes advantage of new features in the C# language and .NET framework. I like it.

One question that came up a few times was "when should I use a mock object framework"? Turns out I've been asked a lot of questions starting with when lately, so I'll answer that question in the next post.

Following Principles

Wednesday, April 9, 2008 by scott
3 comments

A dictionary definition of principle often uses the word "law", but principles in software development still require judgment. Sometimes the judgment requires some technical knowledge, like knowing the strengths and weaknesses of a particular technology. Other times the judgment requires some business knowledge, like the ability to anticipate where change is likely to occur.

Asking someone to make a sensible judgment about a principle is difficult when all you see is a snippet of code in a blog. The code is outside of its context. Take Leroy's BankAccount class. We don't really know what sort of business Leroy works for, or even what type of software Leroy is building. Nevertheless, let's apply a few principles to see what's bothering Leroy.

Remaining Single

Does Leroy's original BankAccount class violate the Single Responsibility Principle? I think so. The class is opening text files for logging, calculating interest, and oh, by the way, it needs to provide all the state and behavior for a financial account, too. Even without knowing the context, it seems reasonable to remove the auditing cruft into a separate class. After writing some tests, and implementing a concrete auditing class, Leroy's BankAccount might look like the following.

public class BankAccount
{        
    
public void Deposit(decimal amount)
    {
        Balance += amount;
        _log.Write(
"Deposited {0} on {1}", amount, DateTime.Now);
    }

  
// ...
  
  
AuditLog _log = new AuditLog();

}

Leroy has an almost infinite number of choices to make before coming up with the above implementation, though. Leroy could have derived BankAccount from an Auditable base class, or forced BankAccount to implement an IAuditable interface. But what guides Leroy to this particular solution in the universe of a million possibilities are other principles - like the Interface Segregation Principle, and Composition Over Inheritance.

An Addiction to Auditing

Leroy might still frown at his class, feeling he has violated the Dependency Inversion Principle. Without any additional information, we have to trust Leroy's judgment when he decides to make some additional changes.

public class BankAccount
{        
    
public BankAccount (IAuditLog auditLog)
    {
        _log = auditLog;
    }

    
public void Deposit(decimal amount)
    {
        Balance += amount;
        _log.Write(
"Deposited {0} on {1}", amount, DateTime.Now);
    }

  
// ...
  
  
IAuditLog _log;
}

Perhaps Leroy already knew about some future changes in his auditing implementation, or perhaps Leroy just wanted to make his class more testable. Some of us view software as a massive heap of dependencies, and we fight to reduce the brittleness created by dependencies using inversion of control and dependency injection techniques. In some environments, this isn't needed. The principles to apply depend on the language you use, the tools you use, and ultimately depend on the problem the software is trying to solve.

Is There Still Something Wrong With This Code?

WWWTC has had a run of 19 episodes. I have some material for at least another 20. Problem is, most of the material deals with API trivia and edge cases you might never see. Interesting? To me, at least, but I'm thinking of introducing more squishy design type entries. I know a lot of people struggle to apply the latest frameworks and libraries, but design questions are always enlightening and produce the most spirited debate, giving us all something we can learn from.

Testing Old Code Is Hard

Wednesday, April 2, 2008 by scott
2 comments

WWWTC #19 presented a BankAccount class from a developer named Leroy and garnered some great feedback. A couple people spotted an actual bug in the interest calculation, which was unintentional. If only Leroy had written some tests for the code…

"Gee, if only I'd written some tests for this code", thought Leroy. Back when Leroy first wrote the code, he considered testing as a job for those irritating people on the other side of the office building. Now, Leroy was looking at changing the BankAccount class to add new features. He was wishing he'd discovered the joys of unit tests earlier than he did. He'd be able to review the existing tests and understand the behavior of the class in more detail, plus, he'd be able to make changes to the class and know immediately if he was breaking any functionality.

"Better late than never", Leroy thought. Writing tests at this point would give him a better understanding of the class and offer the safety net he needed for the upcoming changes. Leroy created a new class library with references to some xUnit assemblies and started in. After a bit of test running, he reached this point:

public class BankAccountTests
{
    [
Fact]
    
public void BalanceShouldEqualFirstDeposit()
    {
        
decimal amount = 200.00m;
        
BankAccount account = new BankAccount();
        account.Deposit(amount);

        account.Balance.ShouldEqual(amount);
    }

    
// ...

    [Fact]
    
public void DepositShouldCreateLogEntry()
    {
        
// ...
    }
}

"Hmm – verifying the log entry is tricky", Leroy thought to himself. "It's too bad this BankAccount class is responsible for formatting and writing the log entry and all that banking logic. Maybe I should do something about that…"

To be continued…

by K. Scott Allen K.Scott Allen
My Pluralsight Courses
The Podcast!