Converting decimal numbers to Roman Numerals in C#

I decided to create a little project to implement converting decimal numbers to Roman Numerals in C#. You can solve this problem in quite a few different ways, I wanted to talk through the pattern based approach that I went for.

The Roman Numerals from 0 to 9 are as follows:

  • 0 = “” (empty string)
  • 1 = I
  • 2 = II
  • 3 = III
  • 4 = IV
  • 5 = V
  • 6 = VI
  • 7 = VII
  • 8 = VIII
  • 9 = IX

To start the project I wrote a set of tests that checked these first 10 cases. I like taking this approach as it allows you to solve for the simple base case, then you can refactor your solution to be more generic. Our first implementation that solves for the first ten numbers is:

public static string ToRomanNumeral(this int integer)
{
       
     var mapping = new Dictionary<int, string>
     {
         {0, ""},
         {1, "I"},
         {2, "II"},
         {3, "III"},
         {4, "IV"},
         {5, "V"},
         {6, "VI"},
         {7, "VII"},
         {8, "VIII"},
         {9, "IX"},
     };

     return mapping[integer];
}

Obviously there is no error checking etc we are just solving for the 10 first cases. I decided to implement the method as an extension method on int as it makes the code look neat as it will allow you to write:

    var romanNumeral = 9.ToRomanNumeral();

The next step is to look at the Roman Numerals up to 100 and see if we can spot any patterns. We don’t want to have to manually type out a dictionary for every Roman Numeral! If we look at the Roman Numeral representation for the tens column from 0 to 100 we find they are:

  • 0 = “” (empty string)
  • 10 = X
  • 20 = XX
  • 30 = XXX
  • 40 = XL
  • 50 = L
  • 60 = LX
  • 70 = LXX
  • 80 = LXXX
  • 90 = XC

We can straight away see that it is exactly the same as the numbers from 0 to 9 except you replace I with X, V with L and X with C. So lets pull that pattern out into something that can create a mapping dictionary given the 3 symbols. Doing this gives you the following method:

private static Dictionary<int, string> CreateMapping(string baseSymbol, string midSymbol, string upperSymbol)
{
    return new Dictionary<int, string>
    {
        {0, ""},
        {1, baseSymbol},
        {2, baseSymbol + baseSymbol},
        {3, baseSymbol + baseSymbol + baseSymbol},
        {4, baseSymbol + midSymbol},
        {5, midSymbol},
        {6, midSymbol + baseSymbol},
        {7, midSymbol + baseSymbol + baseSymbol},
        {8, midSymbol + baseSymbol + baseSymbol + baseSymbol},
        {9, baseSymbol + upperSymbol},
    };
}

We can now call the above method with the symbols for the column we want to calculate passing in the correct symbols. So for the units column we would write:

    var unitMapping = CreateMapping("I", "V", "X");

Now we have this we it is straight forward to create the mapping for the hundreds column. To complete our implementation we want to add some error checks as we are only going to support Roman Numerals from 0 to 4000. The full solution is now quite trivial. We simply check the input is in our valid range (between 0 and 4000). Then we loop through each column looking up the symbol for that column in our mapping dictionary that we generate using our function above. Then we simply concatenate the symbols together using a StringBuilder and return the result.

The full solution with all of the tests is available on my GitHub repository: https://github.com/kevholditch/RomanNumerals.

Advertisements

An easy way to test custom configuration sections in .Net

Due the way the ConfigurationManager class works in the .Net framework it doesn’t lend itself very well to testing custom configuration sections.  I’ve found a neat solution to this problem that I want to share.  You can see all of the code in the EasyConfigurationTesting repository on github.

Most of the problems stem from the fact that the ConfigurationManager class is static. A good takeaway from this is that static classes are hard to test.

One approach to testing your own custom config section would be to put your config section in an app.config inside your test project.  This would work to the extent you could read the configuration section from it and test each value but it would be hard, error prone and hacky to test anything other than what was in the app.config file when the test ran.

In the config demo code that is on github the config section we are trying to test has a range element allowing you to set the min and max.  We want to test that we can successfully read the min and max values from the config and what happens in different scenarios like if we omit the max value from the config section.  Take a look at how readable the following test is:

TestAppConfigContext testContext = BuildA.NewTestAppConfig(@"<?xml version=""1.0""?>
            <configuration>
              <configSections>
<section name=""customFilter"" type=""Config.Sections.FilterConfigurationSection, Config""/>
              </configSections>
              <customFilter>
                <range min=""1"" max=""500"" />
              </customFilter>
            </configuration>");


var configurationProvider = new ConfigurationProvider(testContext.ConfigFilePath);
var filterConfigSection = configurationProvider.Read<FilterConfigurationSection>(FilterConfigurationSection.SectionName);

filterConfigSection.Range.Min.Should().Be(1);
filterConfigSection.Range.Max.Should().Be(500);            

testContext.Destroy();

Notice how we can pass in a string to represent the configuration we want to test, get the section based upon that string, assert the values from the section and then destroy the test context.

Under the covers this works by creating a temporary text file based upon the string you pass in. That temporary text file is then set as the config file to use for ConfigurationManager. The location of the temporary file is stored in the TestAppConfigContext class which also has a helpful destroy method to clean up the temporary file after the test is complete.

By using the builder pattern it makes the test very readable. If you read the test out loud from the top it reads “build a new test app config”. Code that describes itself in this way is easy to understand and more maintainable.

A cool trick that I use inside the builder is to implement the implicit operator to convert from TestAppConfigBuilder to TestAppConfigContext. This means that instead of writing:

var testContext = BuildA.NewTestAppConfig(@"...").Build();

You can write:

TestAppConfigContext testContext = BuildA.NewTestAppConfig(@"...");

Notice on the second row you can omit the call to Build() because the implicit operator takes care of the conversion (which incidentally is implemented as a call to build). In this case you could argue that you like the call to Build() as it means you can use var rather than the type but I personally prefer it.

With this pattern we can easily add more tests with different config values:

TestAppConfigContext testContext = BuildA.NewTestAppConfig(@"<?xml version=""1.0""?>
            <configuration>
              <configSections>
                <section name=""customFilter"" type=""Config.Sections.FilterConfigurationSection, Config""/>
              </configSections>
              <customFilter>
                <range min=""1"" />
              </customFilter>
            </configuration>");


var configurationProvider = new ConfigurationProvider(testContext.ConfigFilePath);
var filterConfigSection = configurationProvider.Read<FilterConfigurationSection>(FilterConfigurationSection.SectionName);

filterConfigSection.Range.Min.Should().Be(1);
filterConfigSection.Range.Max.Should().Be(100);

testContext.Destroy();

In the test above we are making sure we get a max value of 100 if one is not provided in the configuration. This gives us the safety net of a failing unit test should someone update this code.

I think this pattern is a really neat way to test custom configuration sections. Feel free to clone the github repository with the sample code and give feedback.

BuilderFramework – a framework for committing and rolling back test setup

In a recent piece of work the need has come up again to write some builder code for use with tests.  I feel passionately that you should take as much care with your test code as you do with your main software code that goes out of the door.  The reason for this is that your tests are your specification.  They prove the software does what it says it is going to do.  Having well written, clean and repeatable tests is vital.  Tests that are hard to maintain and brittle get ignored when they aren’t working.  Unfortunately you hear phrases like “Oh don’t worry about that test it’s always broken” all too often.

Part of the reason that a lot of tests I see out in the real world aren’t repeatable is that they rely on 3rd party systems that they can’t control very easily.  The biggest one of these is a database.  I’ve seen acceptance tests relying on a certain set of products having certain attributes in a database.  It’s not hard to see why this isn’t a great idea.  As products change in the database the tests start breaking.

To fix this problem a nice approach is to use the builder pattern to build setup your data in a certain way, run your test and then roll the data back to how it was before.  This is something that I have written various times so I’ve decided to start an open source project on github.  The product will provide the boiler plate code so you can just concentrate on writing the steps.

The project will have an interface that you have to implement that looks like this:

public interface IBuildStep
{
    void Commit();
    void Rollback();
}

It doesn’t get any more straight forward than that. Once you have written a build step you will be able to add it to the main builder in 2 ways. The first way is you can just pass in an instance:

var builder = new Builder()
                    .With(new MyStep());

The second way is that you can provide a type that can build your step. This allows you to write a builder that can build up a class using a fluent interface and just plug it in. For example if I had a builder:

public class MyStepBuilder
{
    private MyStep _myStep;

    public MyStepBuilder()
    {
        _myStep = new MyStep();
    }
    
    public MyStepBuilder WithValue(int value);
    {
       _myStep.Value = value;
    }
    // more methods here to setp all of the properties on _myStep
    // ...

    public MyStep Build()
    {
       return _myStep;
    }
}

Then you would be able to plug that builder into the main builder giving you a fluent interface:

    var builder = new Builder()
                        .With<MyStepBuilder>(s => s.WithValue(3)
                                                   .Build());

Either way once you have an instance of the builder you can then commit your steps by calling commit and then roll them back by calling rollback.

Keep an eye on the github project to see how this developed. If you like the idea or have any thoughts about how it can be improved please give me a shout.

Mocking Frameworks in .Net

As a contractor I have seen a lot of different companies’ code bases and been on many different projects. Most companies now employ TDD (which is a good thing). This means that often you need a mocking framework. Mocking frameworks are ten to the dozen and I have used many different ones over the years.

The most common mocking framework in .Net that I have come across by far is Moq. I quite like Moq but the syntax is a bit clunky. For example to setup a mock repository to return a fake customer:

 var mockRepository = new Mock();
 mockRepository.Setup(m =&gt; m.GetCustomer(It.IsAny()).Returns(new Customer{ Id = 1234, Name = "Fred" });
 var customerController = new CustomerController(mockRepository.Object);
 

What I don’t like is that the variable mockRepository is not an ICustomerRepository it is a Mock<ICustomerRepository>. The Mock is a wrapper around your type. This means that when you inject your mock into the class you are testing you need to use the .Object property as can be seen on line 3 above.

Compare this to FakeItEasy:

 var mockRepository = A.Fake();
 A.CallTo(m =&gt; m.GetCustomer(A.Ignored).Returns(new Customer{ Id = 1234, Name = "Fred" });
 var customerController = new CustomerController(mockRepository);
 

This feels so much cleaner to me because this time mockRepository variable is a ICustomerRepository. The A.Fake<T>() method is a factory method from the FakeItEasy library that does some clever work with a dynamic proxy to fill the provided interface (in this case ICustomerRepository) on the fly. This also means that when we pass the mock into our CustomerController this time we just pass mockRepository, we don’t need to use the .Object extension which feels much cleaner (see line 3 in the 2nd snippet above).

Which mocking frameworks have you used? What are the pros/cons?