# Monday, October 31, 2011

I recently put together an Entity Framework Code First demo that I presented to my colleagues at Skyline Technologies.

The demo includes:

  • Generating DB from POCO’s
  • Fluent and Attribute EF configuration examples
  • Creating Relationships (1 –> Many, Many –> Many)
  • Seeding Data
  • Using a separate DB instance for integration testing
  • How using Data Annotations saves you time in MVC
  • New Features Coming In EF vNext
    • Enums
    • Spatial Data Type

I put the code up on GitHub so if you are looking for an EF Code First kick starter took a look!

posted on Monday, October 31, 2011 7:35:41 AM (Central Standard Time, UTC-06:00)  #    Comments [3]
# Saturday, October 29, 2011

My latest project was being done in ASP.NET MVC3 and I needed to do some date validation that was beyond what was available out-of-the-box.  I Googled around the inter-webs for awhile and couldn’t find anything that met my needs so I decided to create my own set of extensions…and while I was at create my NuGet package and CodePlex project.

For some reason the validation attributes available for the Date data type are non-existence in MVC.  You can compare to another model field, but that only checks for equality.  You can use regular expressions, which is not fun, and you can only compare against static values, or you can create your own validation attributes…which is the route I chose.

I created custom validation attributes that I found that I needed in my projects and packed some up to make available to the masses.

EzValidation contains validation for:

  • Equal, NotEqual, Greater, Less, GreaterOrEqual, LessOrEqual
    • Available for all Primitive Data Types (including nullable)
    • Compare to another field in the Model
        1. [Equal("Email")]
        2. public string ConfirmEmail { get; set; }
    • Compare to a specific value
        1. [NotEqual("|28|")]
        2. public int Age {get; set;}
    • Compare to Current Date (Dates and Strings only)
        1. [Greater("CompareToCurrentDate")]
        2. public DateTime ADateInTheFuture { get; set; }
    • Compare to Yesterday's Date (Dates and Strings only)
        1. [Less("CompareToYesterday")]
        2. public DateTime DateBeforeYesterday { get; set; }
    • Compare to Tomorrow's Date (Dates and Strings only)
        1. [GreaterOrEqual("CompareToTomorrow")]
        2. public DateTime DateAfterTomorrow { get; set; }

     

    The source Code is available on CodePlex.

    The package can be installed via NuGet.  “package-install EzValidation"

    posted on Saturday, October 29, 2011 7:09:00 PM (Central Daylight Time, UTC-05:00)  #    Comments [1]
    # Sunday, July 03, 2011

    Earlier this year during Chicago Code Camp 3, I had the privilege of sitting down with Clark Sell and Marc Nichols and recording my first podcast.  Clark and Mark are the duo behind Developer Smackdown.  If you are not familiar with Developer Smackdown I suggest you take a listen.  In my musing, as Clark and Marc refer to the episodes, we discuss a topic very near and dear to my hear, Test-driven Development.  Take a listen and let me know what you think.

     TDD With Keith Burnell

    posted on Sunday, July 03, 2011 8:30:00 PM (Central Daylight Time, UTC-05:00)  #    Comments [2]
    # Sunday, May 22, 2011

    Last weekend I presented a session at the third annual Chicago Code Camp entitled: Test-driven Development in .NET – Tips, Tools, and Techniques.  The session was standing room only and carried into the commons area afterwards with some excellent questions from attendees.  What is greater than that is that the questions didn’t stop there, they kept coming via email.  One question in particular has stuck with me because it was a hurdle I myself had to overcome early on in my TDD adventures.

    The question boiled down to how do you test code the depends on ASP.NET, specifically Web Configuration and Application Settings?  So I thought I would put together a blog post how this can be done, and how it should be done.

    To set the stage…I have a simple ASP.NET web application with one page and one class.  The page load method calls the one method in the class that returns an app setting stored in the web config file.

    Index.aspx.cs
    1. namespace WebApp
    2. {
    3.     public partial class Index : System.Web.UI.Page
    4.     {
    5.         protected void Page_Load(object sender, EventArgs e) {
    6.             lblValue.Text = SomeClassThatNeedsTesting.GetSomeStringValue();
    7.         }
    8.     }
    9. }

    SomeClassThatNeedsTesting.cs
    1. namespace WebApp
    2. {
    3.     public static class SomeClassThatNeedsTesting
    4.     {
    5.         public static string GetSomeStringValue() {
    6.             return System.Web.Configuration.WebConfigurationManager.AppSettings["MyAppSettingValue"];
    7.         }
    8.     }
    9. }

    Your first option to getting your tests to run and return the configuration and/or app settings is to tell your tests to run under the ASP.NET host process and not the VSTest host process and also tell what url to run the test under.

    SomeClassThatNeedsTesting_Test
    1. [TestMethod]
    2. [HostType("ASP.NET")]
    3. [UrlToTest("http://localhost:2356/Index.aspx")]
    4. [AspNetDevelopmentServerHost("$(SolutionDir)\\WebApp")]
    5. public void GetSomeStringValue_ShouldReturn_NonNull_NonEmpty_String() {
    6.     var val = WebApp.SomeClassThatNeedsTesting.GetSomeStringValue();
    7.     Console.WriteLine(val.ToString());
    8.     Assert.IsFalse(string.IsNullOrEmpty(val));
    9. }

    If you run this you will see that the test passes…eventually…after Casini is started and the test runner twiddles its thumbs for a bit.  Speed is my first issue with setting up your test to run in this fashion.  My second issue is that you aren’t testing the ASP.NET configuration framework so why would you need to add all this extra plumbing to make your code take that route?  There is a better option!

    Since we really don’t care how or where are value comes from we just need some sort of value returned so we can test our method, we can easily add a thin layer of abstraction and mock the pieces of code that depend on ASP.NET.

    Lets start by creating an interface for a simple class that reads application settings.

    IAppSettingsReader.cs
    1.  
    2. namespace WebApp {
    3.  
    4.     public interface IAppSettingsReader {
    5.  
    6.         string GetAppSettingValue(string settingKey);
    7.     }
    8. }

    Now we can implement the interface and add the actual code to read the app settings from the web config file.

    AppSettingsReader
    1. namespace WebApp {
    2.  
    3.     public class AppSettingsReader : IAppSettingsReader {
    4.  
    5.         public string GetAppSettingValue(string settingKey) {
    6.             if (string.IsNullOrEmpty(settingKey)) throw new NullReferenceException("settingKey is required");
    7.             return (WebConfigurationManager.AppSettings[settingKey]);
    8.         }
    9.  
    10.     }
    11. }

    Next we will modify our class that needs testing to use the new AppSettingsReader.  Because our goal is to eventually be able to mock the settings reader we need to invert the control of the dependency and provide a mechanism for injecting the dependency.  The change is fairly straightforward.

    SomeClassThatNeedsTesting
    1. namespace WebApp {
    2.  
    3.     public class SomeClassThatNeedsTesting {
    4.  
    5.         private readonly IAppSettingsReader _settingsReader;
    6.  
    7.         public SomeClassThatNeedsTesting(IAppSettingsReader settingsReader) {
    8.             _settingsReader = settingsReader;
    9.         }
    10.  
    11.         public string GetSomeStringValue() {
    12.             return _settingsReader.GetAppSettingValue("MyAppSettingValue");
    13.         }
    14.     }
    15. }

    Now we have introduced a breaking change and need to modify our page and our test to accommodate the change to SomeClassThatNeedsTesting.

    Index.aspx.cs
    1. namespace WebApp {
    2.  
    3.     public partial class Index : Page {
    4.  
    5.         protected void Page_Load(object sender, EventArgs e) {
    6.             var someClass = new SomeClassThatNeedsTesting(new AppSettingsReader());
    7.             lblValue.Text = someClass.GetSomeStringValue();
    8.         }
    9.     }
    10. }

    SomeClassThatNeedsTesting_Test
    1. namespace TestProject {
    2.  
    3.     [TestClass]
    4.     public class SomeClassThatNeedsTesting_Tests {
    5.  
    6.         [TestMethod]
    7.         [HostType("ASP.NET")]
    8.         [UrlToTest("http://localhost:2356/Index.aspx")]
    9.         [AspNetDevelopmentServerHost("$(SolutionDir)\\WebApp")]
    10.         public void GetSomeStringValue_ShouldReturn_NonNull_NonEmpty_String_ASP() {
    11.             SomeClassThatNeedsTesting someClass = new SomeClassThatNeedsTesting(new AppSettingsReader());
    12.             string val = someClass.GetSomeStringValue();
    13.             Console.WriteLine(val);
    14.             Assert.IsFalse(string.IsNullOrEmpty(val));
    15.         }
    16.     }
    17. }

    At this point we can run our test from above and, after we have taken a bathroom break, checked Twitter, and made a sandwich, we will notice that the test still passes.  This is true because all we have done is add a layer of abstraction.  We have not changed the core functionality of the process.  Now that the layer of abstraction is in place we can write another test and this time instead of writing more code to please ASP.NET lets drop that dependency completely by mocking it.

    To implement our mock I am going to use my mocking tool of choice, RhinoMocks.  (I am purposefully not supplying a URL here because you should be using NuGet to get your packages!)

    Here is our new and improved test.

    New And Improved Test
    1. [TestMethod]
    2. public void GetSomeSringValue_ShouldReturn_NonNull_NonEmpty_String_Mocked() {
    3.     //Arrange
    4.     string myAppSettingValue = "This is my expected mocked setting value";
    5.     MockRepository _repository = new MockRepository();
    6.     IAppSettingsReader mockSettingsReader = MockRepository.GenerateStrictMock<IAppSettingsReader>();
    7.     mockSettingsReader.Expect(msr => msr.GetAppSettingValue("MyAppSettingValue")).Return(myAppSettingValue).Repeat.Once();
    8.     _repository.ReplayAll();
    9.     //Act
    10.     SomeClassThatNeedsTesting someClass = new SomeClassThatNeedsTesting(mockSettingsReader);
    11.     string val = someClass.GetSomeStringValue();
    12.     //Assert
    13.     Assert.AreEqual(myAppSettingValue, val, "Wrong value returned from GetSomeSringValue");
    14. }

    If you take a look at the test you can see that the first thing that I did was create my mock AppSettingReader and set my expectations.  After that I instantiated my class under test and passed in the settings reader mock.

    Hope you found this useful!  Complete code is available here!

    posted on Sunday, May 22, 2011 7:17:23 PM (Central Daylight Time, UTC-05:00)  #    Comments [0]
    # Saturday, April 02, 2011

    Unit testing certainly does give you the developer a warm fuzzy but that warm fuzzy can only get you so far.  In the end you still have to make sure all your little pieces of code/functionality play nice together.  This requires integration testing and if we are going to do any sort of testing that we actually expect to be performed on a regular basis we have to automate it.  Automated integration testing often gets neglected and is substituted with manual testing, which delays finding issues and adds time to the project timeline.  The reason that integration testing is often neglected is that it requires touching actual data. 

    Why is this is an issue:

    1. Someone has to take the time create the data for the testing.
    2. The data has to be reset after each test run

    All of this requires a lot of work, coordination…and a DBA [cringe]!

    Let me introduce a scenario where all that is not required.  Why can’t we wrap our tests in a Transaction?

    Here’s what I am thinking:

    1. Have a local empty copy of the database.
    2. Either in a test-by-test basis or test-suite basis
      1. Start a transaction (either at the start of your test or on build-up of the test suite)
      2. Create your data and put it in the DB
      3. Perform your tests on the data you just created and inserted
      4. Rollback the transaction
    3. … And Repeat

    Here is an example:

    1.         [TestMethod]
    2.         public void GetAllEligible_ShouldReturn_All_Attendess_InThe_Database_Where_IsEligible_Equals_True() {
    3.             using (new TransactionScope()) {
    4.                 //Arrange
    5.                 int expectedCount = 1;
    6.                 Attendee attendee1 = new Attendee {FirstName = "Joe", LastName = "Smith", IsEligible = true};
    7.                 Attendee attendee2 = new Attendee {FirstName = "Randy", LastName = "Jones", IsEligible = false};
    8.                 using (var dc = new DayOfDotNetDataContext()) {
    9.                     dc.Attendees.InsertAllOnSubmit(new List<Attendee> {attendee1, attendee2});
    10.                     dc.SubmitChanges();
    11.                 }
    12.                 //Act
    13.                 IAttendeeRepository attendeeRepository = new AttendeeRepository();
    14.                 IList<AttendeeDTO> attendees = attendeeRepository.GetAllEligible();
    15.                 //Assert
    16.                 attendees.Count.ShouldEqual(expectedCount, "Wrong number of attendess");
    17.             }
    18.         }

    You can see that the first line of my test starts a transaction scope.  I then create some data and add it to my empty database.  Now, remember this database needs to be empty as to not mess up your expectations.  After the data has been created I then perform the operation I am testing and assert the results.

    You may be confused by the lack of a “Rollback” statement.  The way TransactionScope works is that it only commits when explicitly told to do so.

    Automated integration testing is a must have and in order to make your life easier follow the steps I have outlined and you will be free to live the TDD dream!

    posted on Saturday, April 02, 2011 2:19:41 PM (Central Standard Time, UTC-06:00)  #    Comments [4]