Void’s Vault

Knowledge source for efficiency.

Unit Testing in C#.Net

This is an overview of some testing possibilities in C.Net with Visual Studio.

I suggest you install NCrunch and NUnit. Starting with that, you will be able to have all the testing framework you need.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
using NUnit.Framework;
class JobsAnalyzerTest
    {
        private const int TOTAL_QUEUED_JOBS = 42;
        private const int TOTAL_ACTIVE_JOBS = 58;
        private const double QUEUED_RATIO = 0.42;

        [Test]
        public void NewInstanceShouldSetupProperties ()
        {
            JobsAnalyzer analyzer = new JobsAnalyzer (TOTAL_QUEUED_JOBS, TOTAL_ACTIVE_JOBS);
            Assert.AreEqual (QUEUED_RATIO, analyzer.QueuedRatio);
        }
    }

It’s that easy! Also, I suggest using FluentAssertions, for some easy to read assertions like:

1
analyzer.QueuedJobs.Should ().Be (TOTAL_QUEUED_JOBS);

Now, unit tests are not often unit tests without some mocks. I’ve looked at two frameworks :

  • Rhino Mocks
  • Moq

I personally prefer Moq at it looks a bit more like Mockito (Java) to me, but both are quite easy to use. Here’s an example with Rhino Mock :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
using Rhino.Mocks;
[Test]
public void ATest()
{
  MockRepository mocks = new MockRepository ();
  HistoryKeeper history = mocks.StrictMock<HistoryKeeper> ();

  estimator = new CoreDemandEstimator (history);
  Expect.Call (history.HasEnoughData ()).Return (false);

  history.Stub (x => x.GetOldestEvent ()).Return (event0);
  mocks.ReplayAll ();

  Assert.AreEqual (6, estimator.EstimateFutureRequestedCores ());
  history.AssertWasCalled(x => x.HasEnoughData (), option => option.Repeat.Times(1));
  mocks.VerifyAll ();
}

As you noticed, we have to use a MockRepository to create mocks. Also, you have to say ReplayAll for the stubs or the Expect to work. The Expect class creates what you need to verify if a method was called during the test. Stub method only creates the stub without any care of how many times the method will be called.

UPDATE: There’s also another way of coding with RhinoMock. You just have to generate a Stub instead of a Mock. That way, the synthax will require you to respect a “Given-When-Then” test structure instead of a “Configure-Test-Replay” structure, which often hides the assertion at the top of a test’s code.

Here’s an example with Moq :

1
2
3
4
5
6
7
8
9
10
using Moq;

Mock<HistoryKeeper> history = new Mock<HistoryKeeper> ();
history.Setup (x => x.HasEnoughData ()).Returns (true);
history.Setup (x => x.GetOldestEvent ()).Returns (event0);

estimator = new CoreSupplyEstimator (history.Object);
Assert.AreEqual (0, estimator.EstimateFutureAvailableCores ());
Mock.Get (history.Object).Verify (x => x.HasEnoughData (), Times.Exactly (1));
}

I prefer Moq because you don’t have to create a MockRepository, you just have to say setup and verify the number of calls if you want after. This verification of the number of times is also quite easy to remember.

I hope it helped!

Oh, and there is one flaw due to the language’s origins (C++) : you have to add the virtual keyword to the stubbed methods for both tools. There is one tool that does not require that for C#, but it’s not a free framework so I have not tried it.