.Net, TDD

AssemblyHelpers now works .NET 4 assemblies.

assemblyhelper-thumb[1] More than two weeks ago I received an email from someone that AssemblyHelper tool doesn’t work with .NET 4 assemblies.

I first mentioned about the tool in Testing internals members with InternalsVisibleTo attribute article.

Here I just want to tell the tool is updated an you can use it against .NET 4 assemblies.  Of course, it still works with assemblies prior version 4.

Feel free to download the updated version.

kick it on DotNetKicks.com

Advertisements
.Net, TDD

Stub HttpContext

Have you ever tried to TDD objects that use HttpContext, HttpResponse, or HttpRequest?  If you did, you probably created wrappers for these classes.  No more.  With .NET 3.5 Microsoft gave us System.Web.Abstractions.dll that extends System.Web namespace.  In this post I’d like to show an example how to stub HttpContext.

Here’s the system under test:

    public class MyContext
    {
        private readonly HttpContextBase _context;

        // This constructor is called by production system.
        public MyContext() : this(new HttpContextWrapper(HttpContext.Current))
        {}

        // Test calls this constructor
        public MyContext(HttpContextBase context)
        {
            _context = context;
        }

        public bool IsItemCached(string item)
        {
            return _context.Cache[item] != null;
        }
    }

Here are the unit tests:

    [TestFixture]
    public class MyContextTester
    {
        private HttpContextBase _contextStub;
        private MyContext _myContext;

        [SetUp]
        public void StartTest()
        {
            _contextStub = MockRepository.GenerateMock<HttpContextBase>();
            _myContext = new MyContext(_contextStub);
        }

        [Test]
        public void IsItemCached_if_Cache_item_is_null_return_false()
        {
            _contextStub.Stub(x => x.Cache).Return(HttpRuntime.Cache);
            Assert.IsFalse(_myContext.IsItemCached("NotThere"), "False is expected.");
        }

        [Test]
        public void IsItemCached_if_Cache_item_is_NOT_null_return_true()
        {
            HttpRuntime.Cache.Insert("I am HERE", "value");
            _contextStub.Stub(x => x.Cache).Return(HttpRuntime.Cache);
            Assert.IsTrue(_myContext.IsItemCached("I am HERE"), "True is expected.");
        }
    }

kick it on DotNetKicks.com

TDD

Review of Roy Osherove’s review.

I just finished watching video by Roy Osherove where he reviews Unit Tests for NetDinner MVC source code.

I liked the video and many points Roy makes are very valid.  However, let me concentrate on the things I didn’t like.

  1. During the video Roy complains how tired he is because it’s 2 AM and he has to record the video.  Who’s fault is that?  I’m as a viewer prefer for my presenter to be fresh and energetic.  Roy, I want to you to teach me, I don’t want to know that you’re tired and that your wife and the kid sleep in another room.
  2. Roy also criticize people who created a test with multiple asserts.  In that particular case the test method had two asserts.  I personally don’t see big problem to use more than one Assert as long as the test name describe what is tested.  He also gives viewers a doctor analogy which I fail to find appropriate.
  3. I was very surprised when after complaining about multiple asserts in a single unit test, Roy recommends using RowTest feature of MbUnit / NUnit.  Roy, how do you describe what is the difference between the first row and second row tests? About three years ago when I was a rookie in TDD world,  I switched to MbUnit from NUnit because of RowTest attribute.  NUnit didn’t have this feature at the time.  However, I stopped using RowTest in my unit tests because it’s not clear what is tested.  However, I still use this RowTests for my integration tests.
    Here are couple of reasons why I stopped using RotTest attribute in my unit tests.

    a. Let assume that you have a test that fails if a value is null or empty string.  Here’s an example:

    [Row(&quot;&quot;)]
    [Row(null)]
    public void UserName_property_should_faile_when_value_is_empty_or_null(string userName)
    

    The problem is that when one of row test fails, it’s hard to see which one failed.

    b. I use TestDriven.NET.  When you run Row tests, TestDriven.NET executes all the row tests. To execute only one row I had to comment out all the other rows.

    Instead of example above, I prefer to create two tests like this:

    [Test]
    public void UserName_property_should_faile_when_value_is_empty()
    
    [Test]
    public void UserName_property_should_faile_when_value_is_null()
    

Roy, no hard feelings.  I personally believe that you are doing a great job of educating people of better development practices.  I myself learned a lot from you.  Just don’t talk like Roy’s way is the only way.

Rhino.Mocks, SystemWrapper, TDD

Tutorial to TDD using Rhino Mocks and SystemWrapper.

In this post I want to introduce to SystemWrapper and demonstrate how it works with Rhino Mocks.
 
SystemWrapper is just a wrapper to .NET system resources like FileInfo, DirectoryInfo, Assembly, … .
 

Why do we need SystemWrapper?

 
Let assume that you’re writing code that creates a directory.  In your unit test you don’t want to create a directory you just want to know that Directory.CreateDirectory(@”C:\MyDir”) was called.  You cannot mock Directory because it’s a static class.  By wrapping Directory in SystemWrapper we can mock Directory object.  Whenever you use Directory, just use IDirectoryWrap interface instead.
 
 

TDD example with Rhino Mocks and SystemWrapper.

 

Goal:

Create a method that tries to create a directory.  If the directory already exists, don’t create it and return false; otherwise, create directory and return true.  Sounds simple enough.
 

Requirements:

Any unit testing framework of your choice.  (I’m using MbUnit v3 which is part of Gallio).
This example is taking advantage of .NET 3.5.  Let me know if you want an example using .NET 2.0.
 
Now we are ready to start.
 

1. Create new Class Library project and name it MockTutorial.

MockTutorial project

2. Rename Class1 to DirectoryInfoSample so your code looks like this:

   1: namespace MockTutorial
   2: {
   3:     public class DirectoryInfoSample
   4:     {
   5:     }
   6: }
 
3. Add a test class.  For simplicity we add our test class in the same file.  The name of the test class will be DirectoryInfoSampleTests.
   1: public class DirectoryInfoSampleTests
   2: {
   3: }
 

4. We need to add references to our unit test framework, Rhino Mocks, and SystemWrapper libraries.

MockTutorial ref 

5. Create our first test.  Remember that our method should try to create directory and there two possible cases (directory doesn’t exist and directory exists). It means that we’ll need two separate tests.  Let’s create the first test when directory already exists.The signature for our method under test will be  public bool TryToCreateDirectory(IDirectoryInfoWrap directory)You also will need to add using statements for your unit testing framework, Rhino Mocks, and SystemWrapper:

   1: using SystemWrapper.IO;
   2: using MbUnit.Framework;
   3: using Rhino.Mocks;
 

 Here comes the test.

   1: [Test]
   2: public void When_try_to_create_directory_that_already_exists_return_false()
   3: {
   4:     var directoryInfoStub = MockRepository.GenerateStub<IDirectoryInfoWrap>();
   5:     directoryInfoStub.Stub(x => x.Exists).Return(true);
   6:     Assert.AreEqual(false, new DirectoryInfoSample().TryToCreateDirectory(directoryInfoStub));
   7: }
Line 4 creates the stub object for DirectoryInfo.
Line 5 stubs Exists property and return true that means that the directory exists.
Line 6 verifies that TryToCreateDirectory method returns false that means that directory wasn’t created because it already exists.
 

6. If you try to compile, it’s going to fail because we didn’t create TryToCreateDirectory method.

Let’s create the method that is going to satisfy our test.

   1: public bool TryToCreateDirectory(IDirectoryInfoWrap directory)
   2: {
   3:     return false;
   4: }
You just can see that we wrote minimum code to make our test pass successfully.
 

7. Next we want to create our second test that expects that directory doesn’t exists and creates it.

   1: [Test]
   2: public void When_try_to_create_directory_that_does_not_exist_return_true()
   3: {
   4:     var directoryInfoStub = MockRepository.GenerateStub<IDirectoryInfoWrap>();
   5:     directoryInfoStub.Stub(x => x.Exists).Return(false);
   6:     Assert.AreEqual(true, new DirectoryInfoSample().TryToCreateDirectory(directoryInfoStub));
   7: }
 
You can see our second test looks very similar to the first one.  The only difference, beside the test name, is that when we stub Exists property we return false instead of true.

If you try to run the test, it will fail because in our test we expect TryToCreateDirectory method to return true.

8. It’s time again to work on our method under test.

   1: public bool TryToCreateDirectory(IDirectoryInfoWrap directory)
   2: {
   3:     if (directory.Exists)
   4:         return false;
   5:  
   6:     return true;
   7: }

Now our tests should pass.  Wait, but how do we know if the directory was created?

 
9. Modify our test to check that Create() method was called.
 
We can change our stub to mock and create an expectation for Create. If you’re confused about Mocks and Stubs, you can read Mocks aren’t Stubs by Martin Fowler.  The last we verify that Create was executed:
   1: [Test]
   2: public void When_try_to_create_directory_that_does_not_exist_return_true()
   3: {
   4:     var directoryInfoMock = MockRepository.GenerateMock<IDirectoryInfoWrap>();
   5:     directoryInfoMock.Stub(x => x.Exists).Return(false);
   6:     directoryInfoMock.Expect(x => x.Create());
   7:     Assert.AreEqual(true, new DirectoryInfoSample().TryToCreateDirectory(directoryInfoMock));
   8:  
   9:     directoryInfoMock.VerifyAllExpectations();
  10: }
 

It will work but I prefer to use stubs and call new method in Rhino Mocks AssertWasCalled.  Isn’t it looks cleaner?

   1: [Test]
   2: public void When_try_to_create_directory_that_does_not_exist_return_true()
   3: {
   4:     var directoryInfoStub = MockRepository.GenerateStub<IDirectoryInfoWrap>();
   5:     directoryInfoStub.Stub(x => x.Exists).Return(false);
   6:     Assert.AreEqual(true, new DirectoryInfoSample().TryToCreateDirectory(directoryInfoStub));
   7:  
   8:     directoryInfoStub.AssertWasCalled(x => x.Create());
   9: }
 
If you run our second test that we just modified, it will fail.  Of course, we never called Create method.

 

10. Call Create() in our TryToCreateDirectory method.

   1: public bool TryToCreateDirectory(IDirectoryInfoWrap directory)
   2: {
   3:     if (directory.Exists)
   4:         return false;
   5:  
   6:     directory.Create();
   7:     return true;
   8: }
 
11. We also can modify our first test to make sure Create() wasn’t call in case when directory already exists.

In this case we call Rhino Mocks method AssertWasNotCalled.

   1: [Test]
   2: public void When_try_to_create_directory_that_already_exists_return_false()
   3: {
   4:     var directoryInfoStub = MockRepository.GenerateStub<IDirectoryInfoWrap>();
   5:     directoryInfoStub.Stub(x => x.Exists).Return(true);
   6:     Assert.AreEqual(false, new DirectoryInfoSample().TryToCreateDirectory(directoryInfoStub));
   7:  
   8:     directoryInfoStub.AssertWasNotCalled(x => x.Create());
   9: }
 
To see all the classes that wrapped by SystemWrapper follow this link.
 
More to come.  I’d like to hear from you what classes would you like to add to SystemWrapper first.
 

kick it on DotNetKicks.com

.Net, C#, MbUnit, Reference Type, TDD

Comparing Reference Types in Unit Tests.

If you’ve done some unit testing, you’re familiar with Assert.AreEqual method.  Have you try to compare two objects that have the same value(s) but the AreEqual method tells you that they are not equal?  For example let assume that we have a class Point:

   1: private class Point
   2: {
   3:   private int _x;
   4:   private int _y;
   5:  
   6:   public Point(int x, int y)
   7:   {
   8:     _x = x;
   9:     _y = y;
  10:   }
  11: }

And we test for the constructor:

   1: [Test]
   2: public void Point_constructor_test()
   3: {
   4:   Point point = new Point(2, 3);
   5:   Assert.AreEqual(point, new Point(2, 3));
   6: }

When I run this test using MbUnit, the assertion fails.  The reason it fails because Point is a reference type.     Actually what is getting compared is objects references (not objects values) and of course they have different references.

One way we could fix it is to make Point a Value Type by replacing class with struct.

   1: private struct Point
   2: {
   3:   private int _x;
   4:   private int _y;
   5:   
   6:   public Point(int x, int y)
   7:   {
   8:     _x = x;
   9:     _y = y;
  10:   }
  11: }

This definitely resolves the issue.

Another thing we could do is implement IEquatable<T> interface:

   1: private class Point : IEquatable<Point>
   2: {
   3:   private int _x;
   4:   private int _y;
   5:  
   6:   public Point(int x, int y)
   7:   {
   8:     _x = x;
   9:     _y = y;
  10:   }
  11:  
  12:   public bool Equals(Point other)
  13:   {
  14:     return (_x == other._x) && (_y == other._y);
  15:   }
  16: }

[Updated] However, MbUnit test still will fail because deep inside MbUnit’s AreEqual calls object.Equal(object).  In order for AreEqual to succeed in this case, it needs to call generic version of AreEqual.  Something like this:

   1: private static bool AreEqual<T>(T expected, T actual)
   2: {
   3:   if (expected is IEquatable<T> )
   4:     return ((IEquatable<T>)expected).Equals(actual);
   5:   return expected.Equals(actual);
   6: }

It means we need to modify our test little bit. Instead of AreEquals method we can use IsTrue one.

   1: [Test]
   2: public void Point_constructor_test()
   3: {
   4:   Point point = new Point(2, 3);
   5:   Assert.IsTrue(point.Equals(new Point(2, 3)));
   6: }

In software development the same problem can be solved many different ways.  I assume that most common solution is going to be comparing some public properties in the object instead of the whole object.

Let assume assume that our Point class has public properties X and Y.  Here’s an example how my test would look:

   1: [Test]
   2: public void Point_constructor_test()
   3: {
   4:   Point point1 = new Point(2, 3);
   5:   Point point2 = new Point(2, 3);
   6:   Assert.AreEqual(point1.X, point2.X);
   7:   Assert.AreEqual(point1.Y, point2.Y);
   8: }

kick it on DotNetKicks.com

.Net, C#, Coding, MbUnit, Rhino.Mocks, TDD

Mock DataTable

Today I had to work with some legacy code.  It was originally written in Delphi and then converted line by line to C#.  Before changing anything in the code I decided to create unit tests and make sure that I have 100% coverage.

One of the thing I had to do in my unit test is to mock DataTable.  Here are the steps I made during mocking.

  1. Create needed columns in a DataTable.
  2. Create a new DataRow.
  3. Assign values to the row.
  4. Finally add the row to the DataTable.

Repeat steps 2- 4 for each row you want to add to your DataTable.

Here’s the example:

   1: [Test]
   2: public void HolidayTest()
   3: {
   4:   MockRepository mocks = new MockRepository();
   5:   ICompanyDAL dalMock = mocks.CreateMock<ICompanyDAL>();
   6:   // Create DataTable
   7:   DataTable fakeHolidays = new DataTable();
   8:   // 1. Add Columns
   9:   fakeHolidays.Columns.Add("Holiday", typeof (DateTime));
  10:   fakeHolidays.Columns.Add("Name", typeof(string));
  11:   // 2. Create new DataRow
  12:   DataRow dayRow = fakeHolidays.NewRow();
  13:   // 3. Assign values to the row
  14:   dayRow["Holiday"] = DateTime.Parse("07/04/2008");
  15:   dayRow["Name"] = "Independence Day";
  16:   // 4. Add the row to the DataTable
  17:   fakeHolidays.Rows.Add(dayRow);
  18:   _pgDate.CompanyDal = dalMock;
  19:   using (mocks.Record())
  20:   {
  21:     Expect.Call(dalMock.GetHolidays()).Return(fakeHolidays);
  22:   }
  23:   using (mocks.Playback())
  24:   {
  25:     DataTable holidays = _pgDate.Holidays;
  26:     Assert.GreaterThan(holidays.Rows.Count, 0);
  27:   }
  28: }

I used Rhino.Mocks as my mocking framework in the example above.

kick it on DotNetKicks.com

.Net, Coding, TDD

Testing internals members with InternalsVisibleTo attribute.

I posted previously about testing non-public members with MbUnit.  I recently found out about InternalsVisibleTo attribute by reading Roy Osherove‘s book The Art of Unit Testing.

To use this attribute, your test assembly must be strong-named.  Then you put InternalsVisibleTo attribute with public key of test assembly into AssemblyInfo.cs file of assembly under test.

 1: [assembly: InternalsVisibleTo("MyAssembly.Tests, PublicKey=XXX")]

I created an Assembly Helper tool that creates the syntax for you.  The tool is working (or should work) with following languages:

  • C#AssemblyHelper
  • Visual Basic
  • Delphi
  • MS C++
  • Chrome

You can get the tool from here.

Steps to use InternalsVisibleTo attribute with the tool.

Let assume that you have Assm_A and Assm_ATests.

  1. Sign Assm_A and Assm_ATests with a Strong Name. You can read about that here.
  2. Compile your assemblies.
  3. Launch Assembly Helper tool .
  4. Select desired language and press on ‘Get Assemblies’ button and navigate to Assm_ATests.dll.
  5. Copy the text into AssemblyInfo file of Assm_A assembly.

Now your tests can access internals members of the assembly under test.

Note: With Assembly Helper tool you can select multiple assemblies at once.

kick it on DotNetKicks.com