Friday, May 22, 2009

Over at los techies now

I got a wonderful opportunity to blog over at Los Techies . I'm not too worried about losing my independence as I see eye to eye with a lot of that community and its a good place to get my idea's kicked around and adjusted by others experiences.

Thursday, May 21, 2009

Context/Spec style testing and my approach to BDD

I borrow heavily my approach to testing from a combination of Ayende's Rhino Tools tests, and my reading of the Rspec beta book. But I think I've stumbled onto something I'm happy with and I can generate reports out of. Let's go over some basic rules first:

  1. Move as much common setup logic to a base class as possible.
  2. Use your class name as the context
  3. methods are rules beginning with "should"
  4. create a new subclass of the base context every time you have a new scenario
Code ends up looking like so:


public class BaseAddVacationContext
{
protected AddVacationRequest submission;
protected IEmailSender _sender;
protected IUserInformation _information;
protected ICrudRepo<LeaveRequest> _leaverepo;
protected LeaveRequest request;
[SetUp]
public virtual void SetUp()
{
_sender = MockRepository.GenerateMock<IEmailSender>();
_information = MockRepository.GenerateMock<IUserInformation>();
_leaverepo= MockRepository.GenerateMock<ICrudRepo<LeaveRequest>>();
submission = new AddVacationRequest(_sender, _information, _emprepo);
request = new LeaveRequest() { UserName = "james" };


}
}
[TestFixture]
public class SpecAddVacationRequestWhenHappyPathOccurs : BaseAddVacationContext
{


[SetUp]
public override void SetUp()
{
base.SetUp();
_information.Stub(x => x.GetManagersEmailAddresses("james")).Return(new[]{"jacob@jonbank.com", "johnny@jonbank.com"});
_information.Stub(x => x.GetUserEmail("james")).Return("james@jonbank.com");
submission.Execute(request);

}
[Test]
public void should_email_all_managers()
{
_sender.AssertWasCalled(x => x.Send(Arg
<Message>.Matches(y => y.To == "jacob@jonbank.com")));
_sender.AssertWasCalled(x=>x.Send(Arg
<Message>.Matches(y=>y.To =="johnny@jonbank.com")));
}

[Test]
public void should_send_email_to_user()
{
_sender.AssertWasCalled(x => x.Send(Arg
<Message>.Matches(y => y.To == "james@jonbank.com")));
}

[Test]
public void should_store_leave_request_in_database()
{
_emprepo.AssertWasCalled(x=>x.Create(Arg
<LeaveRequest>.Matches(u=>u == request)));
}
}



So here we have:
  • A setup that you need to override and call to setup context specific behavior
  • small small tests and asserts.
  • limited setup on mocks, you can use handrolled mocks or the real classes if you prefer (which I do often).
  • Use AssertWasCalled instead of .Expect() on my mocks
I'll post more examples of this as they come up.

Monorail ActiveRecord and NHibernate

Ran into this at work yesterday and wanted to save others some aggravation:

Scenario: Need To query a value on a page repeatedly. Another 3rd party program is modifying the data you are querying. (in my case to generate new account numbers, could be anything)

Bad Result: 3rd Party Program changes data in background your page does not update the new value.

So my ActiveRecord query before looked something like so:


ActiveRecordMediator.FindAll(Restrictions//you don't really care do you)


now instead grab the underlying session object:


ISession session =ActiveRecordMediator.GetSessionFactoryHolder().CreateSession(typeof(DpAcct))
var query = session.CreateQuery(//again you dont care)
var list = query.List()
session.Close()


This may not be the best way and my Nhibernate knowledge is rudimentary once you start getting into Sessions, Scopes and Flushing, but it worked to get an ActiveRecord user by.

It seems the cache doesn't know when to refresh when a third party application is involved. This is logical as the caching would be more expensive if it did.

Typemock Isolater and ASP.net Bundle -FREE

Pretty obvious marketing, but this is an awesome deal so I wanted you my readers in on it too. What kind of irresponsible blogger would I be? So without further ado:

Unit Testing ASP.NET? ASP.NET unit testing has never been this easy.

Typemock is launching a new product for ASP.NET developers – the ASP.NET Bundle - and for the launch will be giving out FREE licenses to bloggers and their readers.

The ASP.NET Bundle is the ultimate ASP.NET unit testing solution, and offers both Typemock Isolator, a unit test tool and Ivonna, the Isolator add-on for ASP.NET unit testing, for a bargain price.

Typemock Isolator is a leading .NET unit testing tool (C# and VB.NET) for many ‘hard to test’ technologies such as SharePoint, ASP.NET, MVC, WCF, WPF, Silverlight and more. Note that for unit testing Silverlight there is an open source Isolator add-on called SilverUnit.

The first 60 bloggers who will blog this text in their blog and tell us about it, will get a Free Isolator ASP.NET Bundle license (Typemock Isolator + Ivonna). If you post this in an ASP.NET dedicated blog, you'll get a license automatically (even if more than 60 submit) during the first week of this announcement.

Also 8 bloggers will get an additional 2 licenses (each) to give away to their readers / friends.

Go ahead, click the following link for more information on how to get your free license.