in Search

cruizer

aspiring to free and open the mind of .NET developers

September 2006 - Posts

  • Sample NMock code

    Okay, I'm posting here my sample code that uses NMock to dynamically create mock objects from interface declarations. It's a very simple system that provides a ForexConverter class. This ForexConverter class performs conversion of money from one currency to another and defers the retrieval of the exchange rate to any implementation of the IExchangeRateRetriever interface.

    Here are the stuff...

    TestForexConverter.cs:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    using NUnit.Framework;
    using NMock2;

    namespace MockDemo1
    {
      [TestFixture]
      public class TestForexConverter
      {
        ForexConverter _converter;
        Mockery _mocks;
        IExchangeRateRetriever _mockRetriever;
        
        [SetUp]
        public void Setup()
        {
          _mocks = new Mockery();
          _mockRetriever = _mocks.NewMock<IExchangeRateRetriever>();
          _converter = new ForexConverter(_mockRetriever);
        }
        [Test]
        public void TestForexCreation()
        {
          Assert.IsNotNull(_converter);
        }
        
        [Test]
        public void TestConvertUSDToPHP()
        {
          const double exchangeRate = 50.48;
          const double testAmount = 100.00;
    // the following code uses NMock to assert that
    // the _mockRetriever's GetRate method was called with the parameters
    // "USD" and "PHP" and that it will return a value of exchangeRate
          Expect.Once.On(_mockRetriever).Method("GetRate").With("USD", "PHP").Will(Return.Value(exchangeRate));
          double inPesos = _converter.Convert("USD", "PHP", testAmount);
          Assert.AreEqual(exchangeRate * testAmount, inPesos, 0.001);
    // the following line says that the test will fail if the above
    // expectation (the call to _mockRetriever's GetRate() method, which
    // is actually called by the _converter) is not met
          _mocks.VerifyAllExpectationsHaveBeenMet();
        }
        
        [Test]
        public void TestConvertSGDToPHP()
        {
          const double exchangeRate = 31.20;
          const double testAmount = 100.00;
    // the following code uses NMock to assert that
    // the _mockRetriever's GetRate method was called with the parameters
    // "SGD" and "PHP" and that it will return a value of exchangeRate
          Expect.Once.On(_mockRetriever).Method("GetRate").With("SGD", "PHP").Will(Return.Value(exchangeRate));
          double inPesos = _converter.Convert("SGD", "PHP", testAmount);
          Assert.AreEqual(exchangeRate * testAmount, inPesos, 0.001);
    // the following line says that the test will fail if the above
    // expectation (the call to _mockRetriever's GetRate() method, which
    // is actually called by the _converter) is not met
          _mocks.VerifyAllExpectationsHaveBeenMet();
        }
      }
    }

    now for IExchangeRateRetriever.cs:

    1
    2
    3
    4
    5
    6
    7
    namespace MockDemo1
    {
      public interface IExchangeRateRetriever
      {
        double GetRate(string fromCurrency, string toCurrency);
      }
    }

    and finally ForexConverter.cs:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    namespace MockDemo1
    {
      public class ForexConverter
      {
        IExchangeRateRetriever _retriever;
        public ForexConverter(IExchangeRateRetriever retriever)
        {
          _retriever = retriever;
        }
        public double Convert(string fromCurrency, string toCurrency, double amount)
        {
          double result = 0.0;
          double exchangeRate = _retriever.GetRate(fromCurrency, toCurrency);
          result = amount*exchangeRate;
          return result;
        }
      }
    }

    Hopefully if you're someone who's interested in using mocks or NMock but you don't know where to start, you can use this sample as a starting point...
    Posted Sep 15 2006, 04:27 PM by cruizer with 7 comment(s)
    Filed under: ,
  • Makes me cringe...

    It makes me cringe to think that I used to espouse a write-code-first-test-them-later approach that I mistakenly called "TDD." Ugh. (see the latter part of the post)

    I haven't been doing MonoRail lately too. Maybe because MonoRail hasn't seen much in the way of progress or innovation since ASP.NET 2.0 came out? I saw some issues with ASP.NET 1.0/1.1 that led me to explore alternatives, but most of those issues were addressed somewhat satisfactorily by ASP.NET 2.0. So somehow, the motivation for going with an alternative web framework is gone...
  • TDD Talk Re-Run

    I'll be having a TDD talk again for MSDN Student Developers' Night on Wednesday, September 13. I'll make sure I'll be early this time Stick out tongue

    If you will be attending, that'll be great Smile Maybe you'd like to give me suggestions on what I can demo. Last time I demoed the construction of a number-to-words converter and an exchange rate calculator that talked to the database, TDD style. Maybe you have other (better) ideas.

    Anyway, here are the links to my PowerPoint slides and sample code:

    Red-Green-Refactor: Test-Driven Development with .NET
    TDD Sample Code

    See you on Wednesday! Smile
    Posted Sep 08 2006, 03:06 PM by cruizer with 1 comment(s)
    Filed under: ,
  • POCO (Plain Old CLR Objects)

    Has this "philosophy" or approach in .NET development caught the attention of many yet?

    POCO of course is the .NET version of POJO (Plain Old Java Objects), which is the approach of designing Java business objects that do not depend on some container or environment like the monstrous EJB.

    I've been practicing this approach lately...no ADO.NET in business objects, no external dependencies, no ConfigurationManager or ConfigurationSettings.AppSettings stuff. Every dependency should be injected via the constructor (or the appropriate method call) and there is heavy reliance on interfaces. This way I can choose to inject any implementation of those interfaces, with various implementations doing either database access or mock functionality. (A while back I was starting to become a fan of the CSLA.NET framework, but lately I'm getting the impression that using it results in non-unit testable code. So now my preference has changed.)

    And I like it. My output is lightweight, testable and predictable. My ASP.NET code behind (since I do web apps practically all the time) feels like I'm just wiring objects up.

    What's your take on this concept?