Sunday, November 23, 2008

Agile Elevator Speech

I've given quite a few "elevator speeches" about Agile.  After giving each speech, I've either failed to deliver my message, or my audience failed to understand. 

Well, I'm giving up on them.  If I can't be successful then I don't want to add to the confusing cacophony of messages about Agile.

Stop Advocating?

No, I am too passionate about software and software teams to give up advocating Agile.  So here is my plan.

I'm going to explain the prizes.  It's too hard to explain the tools, so I'll give them the good stuff up front.

Why?  Because it's too complex (and important) of a topic to discuss in short time.  So in paraphrase here is what I'll tell them:

When constructing software as a team, I don't care what methodology you're using as long as the team can achieve these goals:

1) Fail fast.
2) Continuously improve the team.
3) Continuously reduce and eliminate waste.
4) Indicate (visually or otherwise) the teams progress.
5) Embrace change.

Agile happens to have some pretty practical tools that will get us there.  If you'd like to join me for lunch, I'd be happy to tell you more!!

Tuesday, November 18, 2008

Testing Expressions With Moq

In one of the tests I was writing using Moq, I needed to test that my repository was called with a particular expression.  After struggling for a bit, I found a solution which I am sharing here in hopes that it will benefit you. 

    1         [Test]

    2         public void Then_Repository_Should_Be_Queried_For_Files_In_Pending_Status()

    3         {

    4             List<JSOFile> dummyFiles = new List<JSOFile>()

    5                       {

    6                           new JSOFile() { STATUS_CD = "P", FILE_NM = "teststring"},

    7                           new JSOFile() { STATUS_CD = "Z", FILE_NM = "test.txt"}

    8                       };

    9 

   10             _repository.Expect(x => x.FindAll(It.IsAny<Func<JSOFile, bool>>()))

   11                 .Callback((Func<JSOFile, bool> del) =>

   12                 {

   13                     dummyFiles = dummyFiles.Where(del).ToList();

   14                 });

   15 

   16             _fileManagement = new FileManagement(_repository.Object, _logger.Object, _file.Object, _jsoFileReader.Object, _jsoFileParser.Object);

   17 

   18             _fileManagement.ProcessReceivedFilesToPending();

   19 

   20             Assert.That(dummyFiles.Count == 1, "Expression passed into the FindAll method was incorrect.");

   21             Assert.That(dummyFiles.FirstOrDefault().FILE_NM == "teststring");

   22 

   23             _repository.Verify();

   24         }


What am I testing?

In the method under test (Line 18 _fileManagement.ProcessReceivedFilesToPending()), I want to ensure that my repository is being queried for the appropriate objects.  In this case, all "JSOFile" objects with the STATUS_CD of "P". 

The meat of this test method is line 10.  This line sets up an expectation that the FindAll(Func<JSOFile, bool>) method will be called from the repository object passed in via constructor (line 16, first parameter). 

(_repository defined as:)

_repository = new Moq.Mock<IRepository>();

The Expect method takes a lamba expression that allows you to set an expectation on the type being mocked.  In addition to setting expectations, you can also define callbacks.  In this example, the callback gets fired when the class under test (_fileManagement) executes the mocked object's FindAll() method.  Line 13 will receive the delegate that was passed to the _repository.FindAll.  To make sure the delegate was what I expected, I execute the delegate against a list of dummy objects.  On lines 20 and 21 I make sure that my list was narrowed down to the object with a status of "P". 

Why go to this trouble?

In the future if my repository call gets changed, this test will fail and alert the developer that they've broken intended functionality.