Property.Settings.Default considered detrimental to unit testing

Storing your application and user settings should be a solved problem. After all, we have done it since the dawn of software development. Yet, the question “What is the best way to store settings?” keeps cropping up. The answers vary widely and quite often spark religious wars.

As interested as I am in why people are so invested in whatever they use, it doesn’t help me decide one way or the other.

Does it really matter? It’s not like it is a life and death decision.

Just use what is provided by your development environment and be done with this already!

Using Visual Studio, that would mean you opt for using Properties.Settings.Default.

The reasons to do so are obvious:

  • It’s the recommended way to store settings for Windows Forms Applications by 283 upvotes on StackOverflow [1], as well as by CodeProject [2] and of course MSDN [3] itself.
  • The Visual Studio Settings designer generated a settings class that allows you to work with your settings in a type safe manner. Much better than the ToString / FromString hell that is ConfigurationManager.AppSettings.
  • It’s quick and convenient. No coding required.

All you need is something like:

    class SettingsMineField
    {
        public Int MethodReadingSomeSetting()
        {
            // <snip>
            string LastFolder = Properties.Settings.Default.LastUsedFolder;
            // <snip>
            return Whatever;
        }

        public void MethodWritingSomeSetting(string newValue)
        {
            // <snip>
            Properties.Settings.Default.LastUsedFolder = newValue;
            Properties.Settings.Default.Save();
            // <snip>
        }
    }

Sounds good, hah?

But… what about testing that those methods do what they are supposed to do and keep doing so in future as well?

Using Properties.Settings.Default throughout your code:

  • You bind yourself hand and foot to whatever storage mechanism you hook up (by default the app.config and user.config files).
  • You turn every function that uses Properties.Settings.Default into something that can only be tested through slow integration tests instead of quick, fast executing and more focused unit tests.
  • You will have a hard time to arrange your tests properly as it turns out that is a lot of work, even somewhat of a hack, to get Properties.Settings.Default to work with test content instead of the actual application and user configuration files. [4], [5]

In short, you dig yourself into a hole when it comes to testing your application. If you care about unit testing your code at all, the reasons not to use Properties.Settings.Default are obvious as well.

What to do? How do you get the benefits of using Properties.Settings.Default without the drawbacks?

Dependency injection comes to mind. Which could look something like this:

    class HappyCamper
    {
        Properties.Settings _Settings;

        public HappyCamper(Properties.Settings useThisSettingsInstance)
        {
            _Settings = useThisSettingsInstance;
        }

        public Int MethodReadingSomeSetting()
        {
            // <snip>
            string LastFolder = _Settings.LastUsedFolder;
            // <snip>
            return Whatever;
        }

        public void MethodWritingSomeSetting(string newValue)
        {
            // <snip>
            _Settings.LastUsedFolder = newValue;
            _Settings.Save();
            // <snip>
        }
    }

However, as Properties.Settings is a sealed class, there is no way to circumvent the standard behavior of that class. And, where the resources mentioned above sought to force the configuration management framework to use files with test content instead of the actual files, you want to go one better.

You want your actual program to reap the benefits of the built-in configuration management, and you want your tests independent of the app.config and user.config files (or any other storage mechanism that the built-in configuration management provides) to make them part of your fast executing unit test suite.

So… you need to sever the umbilical cord between the code using settings and the configuration files. If that sounds like breaking a dependency to you: Yay! That is exactly what it is.

If you can’t change or easily influence the (default) behavior of some built-in class, the answer is to insulate your code from the trouble by introducing a layer over which you do have total control. Whether you do so by inheritance or composition doesn’t matter. Either method will provide you with the seams you need to fake the settings used by the code under test.

Inheritance has the advantage of making all standard behavior immediately accessible with very little extra code. Composition takes a bit more work: you need to “replicate” the properties and methods the rest of your code needs and patch them through to the wrapped class. Despite that, I generally prefer composition. It ensures that the properties and methods of and the types used by the wrapped class do not leak into the rest of my code.

As the Properties.Settings class is sealed, inheritance is out.

Wrapping Properties.Settings for our example above:

    class HappySettings
    {
        Properties.Settings _Settings;

        public HappySettings()
        {
            _Settings = Properties.Settings.Default;
        }

        public string LastUsedFolder 
        { 
            get { return _Settings.LastUsedFolder; } 
            set { _Settings.LastUsedFolder = value; } 
        }
        public void Save() { _Settings.Save(); }
    }

Which allows the SettingsMineField class that we started with to become:

    class EvenHappierCamper
    {
        HappySettings _Settings;

        public EvenHappierCamper(HappySettings useThisSettingsInstance)
        {
            _Settings = useThisSettingsInstance;
        }

        public Int MethodReadingSomeSetting()
        {
            // <snip>
            string LastFolder = _Settings.LastUsedFolder;
            // <snip>
            return Whatever;
        }

        public void MethodWritingSomeSetting(string newValue)
        {
            // <snip>
            _Settings.LastUsedFolder = newValue;
            _Settings.Save();
            // <snip>
        }
    }

Which in turn allows your unit tests to provide EvenHappierCamper with any instance of a HappySettings test descendant that you wish, leaving us with:

Mission accomplished!

You get the benefits of using Properties.Settings.Default without the drawbacks!

Enjoy!

What is the one code practice that has you foaming at the mouth because it cramps your unit testing style? I’d love hearing from you by email or in the comments.

[1] Best practice to save application settings in a Windows Forms Application
[2] Windows Forms User Settings in C#
[3] Application Settings Overview
[4] How do I select a .Net application configuration file from a command line parameter?
[5] Change default app.config at runtime

Posted in Software Development
Tags: , , , ,

Why it pays to read more than just the first compiler message

Error messages are frustrating. Especially when you can’t figure out why you are getting them.

Take this bit of code:

    private class MountainComparer : Comparer<Mountain>
    {
        public int Compare(Mountain x, Mountain y)
        {
            // compare the two mountains
            // for the purpose of this tests they are considered equal when their identifiers (names) match
            return x.Name.CompareTo(y.Name);
        }
    }

It produces a 'TestProject.ComparingCollections.SimpleDataAccessLayer_Tests.MountainComparer' does not implement inherited abstract member 'System.Collections.Generic.Comparer<ActualProject.ComparingCollections.Mountain>.Compare(ActualProject.ComparingCollections.Mountain, ActualProject.ComparingCollections.Mountain)' error for the MountainComparer class.

Wah?

What do you mean? The method is there. I am implementing it! I can see it right there!

Guess not. The compiler is rarely wrong.

So why is it complaining?

There is a clue in a warning message the compiler produces in addition to the error: 'TestProject.ComparingCollections.SimpleDataAccessLayer_Tests.MountainComparer.Compare(ActualProject.ComparingCollections.Mountain, ActualProject.ComparingCollections.Mountain)' hides inherited member 'System.Collections.Generic.Comparer<ActualProject.ComparingCollections.Mountain>.Compare(ActualProject.ComparingCollections.Mountain, ActualProject.ComparingCollections.Mountain)' on the Compare method itself.

And that warning message even tells you how to solve the error: To make the current member override that implementation, add the override keyword. Otherwise add the new keyword.

When you do that, ie change

    public int Compare(Mountain x, Mountain y)

to

    public override int Compare(Mountain x, Mountain y)

then both the warning and the error disappear.

You’ll often find the solution to an error message right in the warnings or hints the compiler produces as a result of the same error in your code.

That is why it pays to read a bit more than just the first error message the compiler produces.

Enjoy!

What compiler error messages have had you stumped and turning to your colleagues or Google?
I’d love hearing from you by email or in the comments.

Posted in Software Development
Tags: , , , , , ,

Why it pays to invest some time learning the syntax and terminology of a language

Syntax is boring. Absolutely boring. So is theory and terminology. But neither is trivial. And neither is superfluous. Not if you want to get up to speed as quickly as possible.

Syntax differs from language to language. Everybody accepts that. Not everybody is as aware that while the concepts of object orientation are the same across object oriented languages, the words used to describe their implementation may differ as well.

And that is a big part of what makes compiler error messages read like the prose from an obscure poet in an extra-terrestrial language.

Mystic error message often become a lot clearer with even the flimsiest of knowledge of a language’s syntax and terminology.

Take this bit of C# code

    namespace TestProject.TestingAbstractBaseClasses
    {
        [TestClass]
        public class Bashful_Tests
        {
            private class Bashful_Tester : Bashful
            {
            }

            private Bashful _Bashful;
    
            protected void ArrangeBashfulInstance
            {
                _Bashful = new Bashful_Tester();
            }
    
            [TestMethod]
            public void DoSomethingUseful_WhenPassedNull_ShouldUseValueProvidedByDescendant()
            {
            }
        }
    }

It gives a “A get or set accessor expected” error.

At the time this had me completely mystified. “Accessor” was an unfamiliar term. The “get” or “set” qualification hinted at properties. In Delphi (the language I use at work) the methods that provide the “get” and “set” behavior for a property are referred to simply as “getters” and “setters”.

Ok, so it has to do with properties.

In Delphi property declarations look like

    property StraightFieldProperty: TypeOfTheProperty read FSomeProperty write FSomeProperty;
    property GetSetMethodProperty: TypeOfTheProperty read GetSomeProperty write SetSomeProperty;

The StraighFieldProperty is syntactic sugar for accessing the FSomeProperty instance field. The GetSetMethodProperty is a bit more than syntactic sugar and specifies that the value is returned by GetSomeProperty and set by SetSomeProperty. In other words: GetSomeProperty and SetSomeProperty are the getter and setter method for GetSomeProperty.

And I wasn’t declaring any properties! I was just declaring and implementing a method. No property even remotely in sight!

Or was I?

To my mind I wasn’t doing anything remotely related to properties in the C# code. Yet the error message was telling me that the C# compiler thought I was.

What the …?

Ego deflated, I had to resort to googling the error message. Judging by the number of search results, I am not the only one stumped by this one (which re-inflated my ego a little).

This is the fixed code

namespace TestProject.TestingAbstractBaseClasses
    {
        [TestClass]
        public class Bashful_Tests
        {
            private class Bashful_Tester : Bashful
            {
            }
    
            private Bashful _Bashful;
    
            protected void ArrangeBashfulInstance()
            {
                _Bashful = new Bashful_Tester();
            }
    
            [TestMethod]
            public void DoSomethingUseful_WhenPassedNull_ShouldUseValueProvidedByDescendant()
            {
            }
        }
    }

Did you spot the difference? [1]

Had I had a clear understanding of how to declare properties in C#, my error would have been clear instantly. But I didn’t. And wasted time. Admittedly not much this time, but this was not the only one and it adds up quickly.

Google is my friend, but switching to a browser window, entering a search, clicking on and reading through search results, judging the answer… That whole shebang costs more than just the time it takes to find the answer you need.

It catapults you out of flow.

So why does it pay to take the time to familiarize yourself with the syntax and terminology that is idiomatic to that language?

Because it will save you oodles of time and a mountain of frustration!

And the best way to consolidate your new found knowledge?

Put together a cheat sheet with the syntax of the main language constructs as well as a list of mystic error messages including their causes and solutions.

Especially the solutions to those error messages!

If someone would have given me a dime for every time I sighed in exasperation “I have seen that message before, I know I have.” and not being able to recollect the way to get rid of it, I would be able to retire by now. Well, ok, probably not, but you know what I mean.

Enjoy!

What compiler error messages have had you stumped and turning to your colleagues or Google?
I’d love hearing from you by email or in the comments.

[1] It is the parenthesis pair after ArrangeBashfulInstance.

Posted in Software Development
Tags: , , , , ,

Why CollectionAssert.AreEqual fails even when both lists contain the same items

Last time you did this, it worked flawlessly. The test you made verified that an item was added and then returned correctly:

  • Retrieve all items into a “before” list.
  • Add an item.
  • Retrieve all items into an “after” list.
  • Manually add the item to the “before” list.
  • Call CollectionAssert.AreEqual to compare the “before plus new” and the “after” lists.

The test passed. Just as it should.

Now you have almost exactly the same test. Only thing that has changed are the items in the lists that you are testing.

And now the test fails.

Why?

Psychic debugging isn’t my strongest skill and any number of a whole bunch of things could be the matter. But I’ll give it a stab, so let’s have a look at the test method.

    public void AddingMountain_Should_StoreIt_And_ReturnIt()
    {
        // Arrange
        List<Mountain> beforePlusNew = new Earth().GetAllMountains();
        Mountain mountain = new Mountain(8848, "Everest");
        
        // Act
        new Earth().AddMountain(mountain);
        List<Mountain> after = new Earth().GetAllMountains();

        // Assert
        beforePlusNew.Add(mountain);
        CollectionAssert.AreEqual(beforePlusNew, after);
    }

Oh, right. Obvious. Who in their right mind would create multiple Earths?

Seriously though, instantiating Earth three times means that the items in the beforePlusNew and after lists may seem but not necessarily be the same.

There is a difference between reference and value equality.

That difference is rather important when you are using CollectionAssert.AreEqual to compare items.

According to MSDN CollectionAssert.AreEqual:

Verifies that specified collections are equal. Two collections are equal if they have the same elements in the same order and quantity. Elements are equal if their values are equal, not if they refer to the same object.

Reading that you would expect that CollectionAssert.AreEqual goes through a loop of sorts, checking the values of items at the same index in expected and actual .

You’d be right.
Well… half right.

A loop is used, but CollectionAssert.AreEqual does not check values itself. It defers to Object.Equals.

Which becomes clear when you read the documentation for the CollectionAssert.AreEqual(ICollection expected, ICollection actual) overload:

Two collections are equal if they have the same elements in the same order and quantity. Elements are equal if their values are equal, not if they refer to the same object. The values of elements are compared using [Equals](http://msdn.microsoft.com/en-us/library/system.object.equals.aspx) by default.

Ah!
This is where the monkey comes out of the sleeve. [1]
I hope.

If Equals determines whether two elements are considered equal, then the test passing in one case and failing in the one you are working on now, must have something to do with the way how Equals compares the elements in your lists.

MSDN has a lot to say on Object.Equals. And it holds the key to the apparent inexplicable behavior that has you pulling your hair out.

I suggest you take some time out at some stage and read it. It does a nice job of explaining the difference between reference and value equality. For now the important thing to notice is that Equals treats reference and value types differently.

According to the docs (paraphrased):

  • Value types are equal if they are of the same type and their public and private fields have the same value.
  • Reference types are equal when they are the same object. For reference types a call to Equals is equivalent to a call to ReferenceEquals. Reference equality means that the object variables refer to the same object.

Well now, isn’t that a bummer. MSDN is lying!

“Elements are equal if their values are equal, not if they refer to the same object.” isn’t true at all! That is only true for value types! What use is that!

Calm down. Equivalent != equal.

Where ReferenceEquals cannot be overridden, Equals can!

In order to get your test to work for lists of mountains (fairly safe bet that this is a class rather than a struct), you could have Mountain override the Equals method and specify exactly when one mountain instance is equal to another mountain instance.

Still, I wouldn’t. Not in this case.

Overriding Equals has a couple of nice little pitfalls.[2] Besides, there is a much simpler way.

The simplest solution is simply to not use CollectionAssert.AreEqual(ICollection expected, ICollection actual).

Huh?

Yes, really. And no, I don’t want you to do it all by hand.

Just use CollectionAssert.AreEqual(ICollection expected, ICollection actual, IComparer comparer).

That overload allows you to tailor the comparison by CollectionAssert.AreEqual to the exact needs of (each of) your test(s).

To use that overload, all you need to do is to add a class that can compare mountains:

    private class MountainComparer : Comparer<Mountain>
    {
        public override int Compare(Mountain x, Mountain y)
        {
            // compare the two mountains
            // for the purpose of this tests they are considered equal when their identifiers (names) match
            return x.Name.CompareTo(y.Name);
        }
    }

In the above example I made it a private class of the test class. You could of course also make it available to all test classes in your test project. Up to you. When you do, I would definitely give it a more descriptive name.

Using a comparer, the call in the test method with which we started this story, would become:

    CollectionAssert.AreEqual(beforePlusNew, after, new MountainComparer());

That’s it. Now you never have to wonder again why CollectionAssert.AreEqual fails when it should pass. Enjoy!

Hitting any roadblocks in getting your code under test? Please do feel free to let me know! I’d love hearing from you by email or in the comments below. I read everything and will try to help where and as best I can.

[1] The monkey comes out of the sleeve: dutch saying.
[2] Like having to override GetHashCode as well, or that you shouldn’t really do it for mutable types, and that if you do it you should really override the == operator. Read the docs on the Equals method for more information.

Posted in Software Development
Tags: , , , , ,

Testing an abstract base class – code example

In the “How do I test an abstract base class if I can’t instantiate it?” post, you found out that you can actually test an abstract base class even though you can’t instantiate one.

The “all you need to do is” end of the post, however, was a bit too abstract for your taste. It left you wondering how to put it all together. So let’s do it together.

Let’s say you have this nice little abstract class:

    abstract class Bashful
    {
        protected abstract string LetDescendantComposeFinalResult(string textToUseInComposition);
        protected abstract string LetDescendantProvideDefault();

        public string DoSomethingUseful(string textToUseInComposition)
        {
            // to implement
        }
    }

In your tests for DoSomethingUseful you want to ensure that Bashful actually defers composing the final result to its concrete descendants. You also want to ensure that Bashful always defers to its concrete descendants to get a default value should the passed in string be null or empty.

The tests themselves aren’t that difficult set up. If Bashful were a concrete class you would code your tests like this:


    [TestClass]
    public class Bashful_Tests
    {
        [TestMethod]
        public void DoSomethingUseful_WhenPassedNull_ShouldUseValueProvidedByDescendant()
        {
            Bashful = new Bashful();

            string testResult = Bashful.DoSomethingUseful(null);

            Assert.AreEqual("Composed:DescendantDefault", testResult);
        }

        [TestMethod]
        public void DoSomethingUseful_WhenPassedEmpty_ShouldUseValueProvidedByDescendant()
        {
            Bashful = new Bashful();

            string testResult = Bashful.DoSomethingUseful(string.Empty);

            Assert.AreEqual("Composed:DescendantDefault", testResult);
        }

        [TestMethod]
        public void DoSomethingUseful_WhenPassedExplicitValue_ShouldUsePassedInValue()
        {
            Bashful = new Bashful();

            string testResult = Bashful.DoSomethingUseful("ProvidedValue");

            Assert.AreEqual("Composed:ProvidedValue", testResult);
        }
    }

But of course this gets you in trouble because Bashful is an abstract class and you are not allowed to create instances of it.

So, as said in the “How do I test an abstract base class if I can’t instantiate it?” post, you need a concrete descendant specifically to test the base class.


    [TestClass]
    public class Bashful_Tests
    {
        private class Bashful_Tester : Bashful
        {
            protected override string LetDescendantComposeFinalResult(string textToUseInComposition)
            {
                return "Composed:" + textToUseInComposition;
            }

            protected override string LetDescendantProvideDefault()
            {
                return "DescendantDefault";
            }
        }
        // ...
    }

Very basic. But that is good. And it is enough. It allows you to see whether LetDescendantComposeFinalResult was used and what was passed into it. And that, after all, is the exact purpose for this concrete descendant of Bashful.

You could now replace

    Bashful = new Bashful();

with

    Bashful = new Bashful_Tester();

and you would be all set, because Bashful is so simple that it doesn’t require more to set it up for testing. But let’s say it were more complicated. Then you could create a helper method to instantiate the class you are testing and provide it with any dependencies or initialization as required by your tests. The idea is to do something like:


    [TestClass]
    public class Bashful_Tests
    {
        // ...
        private Bashful _Bashful;

        protected void ArrangeBashfulInstance()
        {
            _Bashful = new Bashful_Tester();
        }

The “Arrange” and “Act” parts of your tests will now look like:

    ArrangeBashfulInstance();

    string testResult = _Bashful.DoSomethingUseful(null);

Note the use of the private _Bashful instead of the local Bashful in the first incarnation of the test methods.

The Bashful class is pretty simple and doesn’t really require anything to set up. But supposing it were a bit more complicated and you wanted each of your tests to use specific test values. What then?

Well, this is where parameters on the “Arrange” method and “helper” methods on the concrete test descendant class come in.

Adding parameters on the ArrangeBashfulInstance method allows each test to set up the instance to meet its specific testing requirements. Adding extra “helper” methods to the concrete descendants is a way to allow your ArrangeBashfulInstance method to do much more than the public interface of the Bashful abstract base class allows.

For the sake of this discussion let’s say that your tests require that they each can control the default value returned by LetDescendantProvideDefault. So you change the Bashful_Tester class to:

    private class Bashful_Tester : Bashful
    {
        protected override string LetDescendantComposeFinalResult(string textToUseInComposition)
        {
           return "ComposedFinalResult:" + textToUseInComposition;
        }

        protected override string LetDescendantProvideDefault()
        {
            return UseAsDefault;
        }

        public string UseAsDefault { get; set; }
    }

That nice, but fairly useless as your tests don’t have access to UseAsDefault because the private _Bashful field is of type Bashful.

A way out is to change that private field to be of type Bashful_Tester.

And that would work.

But…

I recommend against it. For one, you would unnecessarily be duplicating code in each test to set the UseAsDefault value. For another it couples your tests way too tightly to the Bashful_Tester interface, when they should be focused on the Bashful class.

The way to have your cake and eat it too is to leave _Bashful declared as being of type Bashful, add a parameter to the ArrangeBashfulInstance method and change it to:

    protected void ArrangeBashfulInstance(string useAsDefault)
    {
        Bashful_Tester tester = new Bashful_Tester();
        tester.UseAsDefault = useAsDefault;
        _Bashful = tester;
    }

That’s it. Enjoy!

Please do feel free to let me know about any roadblocks you hit by email or in the comments below! I promise I read everything and will try to help where I can.

Posted in Software Development
Tags: , , , , , ,

Test Driven Development: stacking bricks or turning on lights

After all the good things you heard about it, you have taken the plunge and are taking your first steps in test driven development. You thought about what your Splendiforous class is supposed to do, wrote the tests and grew the implementation for all its methods.

This TDD thing really makes sense. Yay!

You’re on a roll and start work on the Magnificent class.

But then… you hit a snag.

Working on the Magnificent class you realize that Splendiforous isn’t quite doing what Magnificent needs. When you change the Splendiforous to meet Magnificent‘s needs, your beautiful tree of green test results turned an ugly screaming red. When you don’t change it, you can’t get the tests for Magnificent to pass.

Catch 22 if ever there was one.

Now what?

Should you fix the broken tests?

Should you have kept the original Splendifourous methods and added different ones to cope with what Magnificent requires?

You scratch your head in bewilderment. This TDD thing looked promising but if it is going to make you fix tests at every turn you take, it is hardly worth the trouble?

Why is everybody else so smitten with it then?

Step back

Let’s take a step back. Couple of things going on here.

You were writing your tests before implementing the methods. Good for you.

But when the requirements for Splendiforous changed, you jumped right in and changed the implementation. Hardly test first now, is it?

You probably should have changed the tests to reflect the new requirements. Tests going red when requirements change is normal. It signals that the implementation doesn’t meet the requirements after all. And then you fixed the implementation so the tests go green again signalling that the implementation once again meets the requirements as reflected by the tests.

But is that all there is to TDD?

Why did you start with Splendiforous?

How did you know that you needed a Splendiforous or what it was supposed to do?

Stacking bricks

The traditional, non-TDD, of doing things is to code all the bricks you need before throwing them together to form a wall. Unfortunately, quite often your bricks don’t play nice with each other and constructing your wall takes quite a bit of reshaping your bricks to make them all stack nicely. You repeat this for every wall in your building and do it again when you come to combining your walls to create the house that you set out to build in the first place.

This inside-out approach is turned on its head when practicing TDD.

Turning on lights

Instead of starting on the inside, you start on the outside: the house’s external appearance.

You think about what the house should do (or be), what can go into the house and what should come out of it. You define your house as a single black box and cut out doors and windows to get stuff in and out of your house.

For each of those doors you decide what should happen when something tries to enter. And you write tests to verify that the house responds appropriately.

To make the tests pass, you turn the black box that represents your house into a white box by deciding what rooms and corridors it needs to serve its purpose. How these should be laid out and how these should be connected by doors.

And you don’t go into the rooms yet. Each room is a new black box. And each black box only gets the doors and windows required by what the house needs it to do (or be).

Of course you can’t test your house without giving each room at least some lighting, turning it gray instead of really black. This is were test doubles come in. Each test double only gets enough lighting to verify that the house responds correctly to what it gets back as it sends its inputs through the appropriate rooms.

Back to your predicament

Practicing TDD would have had you starting on the outside. With Magnificent. Defining what Magnificent should do, writing the tests for it and making the tests pass would have brought the need for Splendiforous to light. And would also have dictated the requirements for Splendiforous.

You would not have had to rack your brain to try and come up with what might be expected of Splendiforous. You would not have had to realize later that what you had concocted wasn’t quite what was needed. And thus the question of fixing tests or adding methods would not even have come up.

Take away

So what’s the takeaway for all this?

When you find yourself “thinking up” what some method or class should be doing:

  • Take a step back and figure out what code will be calling it. Rinse and repeat until you are at the edges of your product with its environment: its interface with the outside world.
  • Work your way back in defining the requirements for each black box as you go.
  • Do it breadth first. So you can evaluate how things fit together and whether that feels awkward or good.
  • Fix (refactor) anything that feels awkward (in the wrong place for example).
  • Only then take the deep dive into each box, illuminating all its details.

That’s it. Now you know how to stop yourself from thinking up code that you don’t need and you won’t have to question what to do with it.

Now go out there and put a sticky on your monitor that reads: “Turn on lights from the outside in” and look at it whenever you catch yourself “thinking up” what some code should do.

Posted in Software Development
Tags: ,

How does my mock know what value I want?

It is early afternoon. You just started your job at Glamorous Inc. Your buddy this morning talked about unit tests. How they want all code to have unit tests but also have code that was written before they started doing that. And they want you to start by getting some of that code under test.

You are raring to go. But now that you are on your own, uncertainty sets in. You have a fair idea what unit tests are. You just never had the opportunity to write that many of them. And these mocking frameworks. You know their purpose, but never used one.

A piece of code is staring back at you. It’s a pretty straightforward function. All it does is read some values from a file to populate some properties.


    class NiceNewJob
    {
      public NiceNewJob(IReader reader)
      {
        Populate(reader);
      }
      
      public string JobTitle {get; private set;}
      public decimal Salary {get; private set;}
      
      private void Populate(IReader reader)
      {
        JobTitle = reader.ReadString("job_title");
        Salary = reader.ReadDecimal("salary");
      }
    }

You know unit tests should not access any files and luckily this class takes an IFileReader in its constructor. So you should be able to mock out this interface. (You are picking up the lingo nicely.)

Looking at similar classes and their tests, you have come up with the test to verify that JobTitle gets populated correctly from the reader passed into NiceNewJob.


    [TestMethod]
    public void 
    {
      var reader = Mock.Create<IReader>();
      var job = new NiceNewJob(reader);
    
    }

So far so good. Creating a new instance of NiceNewJob should have used reader to read values into its properties. So you should be able to write an Assert on the JobTitle value. Something like.

      Assert.AreEqual(job.JobTitle, /*expected value*/);

Gah!

What do you use for the expected value?!

It should be something predictable. Something that keeps the same value regardless of when, where or how often it is executed. Of course the IReader mock should return that value when NiceNewJob calls for it.

But how? How, for Pete’s sake, would that mock know what value you coded as the expected value?

Hang on to your hat.

Mocking frameworks may seem like magic, but really they are not. They are code just like all other code. And while a mocking framework can save you a lot of (tedious) manual coding of your test doubles, it can’t read your mind. Sorry.

This line


      var reader = Mock.Create<IReader>();

is instructing the mocking framework to create a new instance of some class implementing the IReader interface. A mocking framework will ensure that all methods of the class or interface to be mocked are provided with “empty” default behavior. That means either doing nothing (void methods) or returning the default value for the method’s return type.

What is still missing is the specific behavior that you need for your specific test.

There is no way for any mocking framework to have anything more than “empty” behavior without being told explicitly what to do. So every mocking framework will have some way for you to instruct the mock to do your bidding. Exactly how varies per framework. An example could be


    Mock.Arrange(() => reader.ReadString()).Returns("Wizard");

A line like that instructs the mocking framework to return “Wizard” whenever ReadString is called on reader.

Now you know how to get your mock to supply NiceNewJob with a predictable test value, you can finish writing your test.


    [TestMethod]
    public void 
    {
      var reader = Mock.Create<IReader>();
      Mock.Arrange(() => reader.ReadString()).Returns("Wizard");
      
      var job = new NiceNewJob(reader);
    
      Assert.AreEqual(job.JobTitle, "Wizard");
    }

Still sounds like magic?

Let’s look at this then as if you did not have a mocking framework and you’d have to code your test double, fake, mock, stub, or whatever you may call it, yourself.

It is not that difficult. You would have to define an IReader test double class yourself and provide implementations for all methods that IReader defines. Any methods you don’t need for your test(s), you can leave “empty”: returning only the simplest value possible (null, 0, "", ...);

For example


    class FakeReader : IReader
    {
      public string ReadString(string key)
      {
        return "Wizard";
      }

      public decimal ReadDecimal(string key)
      {
        return 666.42;
      }

      public int ReadInteger(string key)
      {
        return 0;
      }

      public void Reset
      {
      }
    }

Using your hand coded test double, the code of your test would read as


    [TestMethod]
    public void 
    {
      var reader = new FakeReader;
      
      var job = new NiceNewJob(reader);
    
      Assert.AreEqual(job.JobTitle, "Wizard");
    }

That’s it. Enjoy!

Now go out there and give your tests some nice predictable values to work with.

Posted in Software Development
Tags: , , , , , , , , , , ,

How do I make a method use a different class in unit tests?

The code you work on has this wonderful simple method. All it does is use a couple of other classes, passing through the parameters it received and setting some properties.

class SimpleClass
{
  public SimpleResult SimplePassThrough(string someString, int someInteger) {
     SimpleResult result = new SimpleResult();
     RealWork work = new RealWork();
   
     if (!work.DoActualWork(someString, someInteger)) {
       result.Error = work.Error;
     }
     return result;
  }
}

As it is such a simple function nobody bothered to write any tests for it. After all, “It only passes through to another class.”

But now that decision has come back to bite you in the a.., because …

Hmm, never mind, the “why” doesn’t really matter anymore. You just happen to be the lucky one to bring this little beauty under test.

As simple as it is, SimplePassThrough is quite untestable.

You know how to create test doubles and use them. But whoever wrote this function, in his or her unending wisdom, decided to instantiate specific classes right there in SimplePassThrough itself. Now how are you going to make it use your test doubles to ensure that all paths in SimplePassThrough are exercised?

Even using a mocking framework there is no way to make this function use your mocks instead of the classes it specifically instantiates!

Grrrr.

Bad news. You are right. You can’t get this function under test without changing it.

Good news is, the changes you need to make are pretty straightforward.

And you don’t need any mocking framework, nor any inversion of control container to do it.

All you need to do is:

  1. Add factory methods to SimpleClass to return instances of the classes that SimplePassThrough needs to do its work.
  2. Change SimplePassThrough to use these factory methods instead of instantiating the classes itself.
  3. Add a test double for RealWork
  4. In your test code, declare a descendant of SimpleClass and override the factory methods for the instances that you want to replace with your test double.
  5. In your tests, instantiate this test descendant so the overridden versions of the factory methods will be used.

Adding factory methods

Factory methods are essentially methods that return (new) instances. The Factory Method pattern as discussed by the Gang of Four, is a little more involved using interfaces and a separate Factory class. The essence is the same: returning references to instances without the caller of the Factory (Method) knowing or caring which exact class (or even which instance) is providing the implementation.

For SimpleClass you need two factory methods. One for SimpleResult, the other for RealWork. The implementation in SimpleClass is straightforward: just return a new instance of the desired class.[1]

The methods still specify exactly which classes SimpleClass will use. Not ideal, but ok for the goal of making SimplePassThrough testable.

Both MakeResult and MakeWork are marked virtual so you can override them to get SimplePassThrough to work with instances of your test doubles.

virtual protected SimpleResult MakeResult()
{
    return new SimpleResult();
}

virtual protected RealWork MakeWork()
{
    return new RealWork();
}

Changing SimplePassThrough to use factory methods

With the factory methods in place you can change SimplePassThrough to work with whatever the factory methods provide. To achieve that, change[2]

    SimpleResult result = new SimpleResult();
    RealWork work = new RealWork();

to

    SimpleResult result = MakeResult();
    RealWork work = MakeWork();

Add a test double for RealWork

The RealWork test double class is where you ensure that all paths in SimplePassThrough can be exercised by overriding DoActualWork. If DoActualWork isn’t virtual yet in the RealWork class, you’ll have to make it so.[3]

    class RealWorkTestDouble : RealWork
    {
        override public Boolean DoActualWork(string aString, int aInt)
        {
            if (aInt != 100)
                Error = 550;

            return aInt == 100;
        }
    }

This test double ensures that you can call it with 100 in aInt to return true and with any other value to return false and set Error to 550. [4]

The class SimpleResult doesn’t need a double because it happens to be a class with just some read/write properties such as Error.

Declaring the SimpleClass test descendant

There is nothing anywhere that says you can only create descendants that will be used in production code. There also is nothing anywhere that says that you are obliged to instantiate the exact class under test in your tests for a class. In fact using a descendant class of the class under test is often a good way to break dependencies and provide “stubs” for methods called by the method under test.

So derive a class from SimpleClass, override its MakeWork method and implement that to return an instance of your RealWork test double.

class CutDescendant : SimpleClass
{
    override protected RealWork MakeWork()
    {
        return new RealWorkTestDouble();
    }
}

Testing SimplePassThrough

SimplePassThrough is indeed a pretty simple function, but it still has logic that you want to stop falling over without someone noticing. So you add two tests. One to verify what should happen when RealWork.DoActualWork returns true and one for when it returns false.

[TestMethod]
public void SimplePassThrough_ActualWork_ReturnsTrue_ShouldReturn_NoError()
{
    // Arrange
    SimpleClass cut = new CutDescendant();

    // Act
    SimpleResult result = cut.SimplePassThrough("Ok", 100);

    // Assert
    Assert.AreEqual(0, result.Error);
}

[TestMethod]
public void SimplePassThrough_ActualWork_ReturnsFalse_ShouldReturn_ErrorFromWork()
{
    // Arrange
    SimpleClass cut = new CutDescendant();

    // Act
    SimpleResult result = cut.SimplePassThrough("Error", 500);

    // Assert
    Assert.AreEqual(550, result.Error);
}

That’s it.

Now go out there and write some tests for that method you thought was untestable

Notes

[1] Would be even better to create factory methods that return an interface instead of an object reference. That way your test doubles don’t have to derive from the original classes used and you don’t have to mark any methods in those classes virtual to provide specific test behavior.

[2] When you forget to change SimplePassThrough to use the factory methods, at least one of the tests should fail: the one checking for a non-zero Error.

[3] When you forget to make DoActualWork virtual and use override in the test descendant, at least one of the tests is likely to fail, probably the one checking for a non-zero Error.

[4] When you use different values in your Asserts than the values that control the behavior of your test doubles, then you ensure that the class you are testing really uses the value it should. Had you same value as you pass in, then your test would not detect whether SimplePassThrough set result.Error to someInteger instead of work.Error.

Posted in Software Development
Tags: , , , , , ,

Why can’t my test access a public constructor?

It’s late in the afternoon. Almost time to go home. Just one issue to finish. A simple class that needs a couple of simple tests. Should be a breeze.

Five minutes later you are ready to bang your head against your desk. The error messages keep flying. And you can’t see why.

If only you could fix this stupid “‘ActualProject.LateAfternoonMisery’ is inaccessible due to its protection level” error, then you’d be home free. Literally.

The class:

namespace ActualProject
{
    class LateAfternoonMisery
    {
        private int _MyInteger;

        public int AwesomeProperty { get {return _MyInteger; } }

        public LateAfternoonMisery()
        {
            _MyInteger = 42;
        }
    }
}

The test:

namespace TestProject
{
    [TestClass]
    public class LateAfternoonMisery_Tests
    {
        [TestMethod]
        public void LateAfternoonMisery_WhenConstructed_AwesomeProperty_ShouldReturn_DefaultValue()
        {
            var myLateAfternoonMisery = new LateAfternoonMisery();
            Assert.AreEqual(myLateAfternoonMisery.AwesomeProperty, 42);
        }
    }
}

Classes don’t get any simpler!
It should just work!
It is as if your Visual Studio and NUnit are plotting against you.

Stop fretting.
You still get to go home early.

There are three easy fixes to this situation.

Classes in C# are by default internal, not public. Which means that they are not visible outside the assembly in which they are used.

So, to fix the error, you can:

1. Add the production unit to your test project

You could add the LateAfternoonMisery.cs file to your test project, but…
I would strongly recommend against that. In Visual Studio it feels like a bad practice to use files outside of the project folder tree. But quite apart from esthetics, you would have to do it for every .cs file you would want to test. And there are much easier ways of getting your hands on your LateAfternoonMisery class and any other classes you want to test. Just read on.

2. Declare the class public instead of internal

    public class LateAfternoonMisery

While that is painless and Visual Studio usually adds the public accessibility when you add .cs files using any of the wizards, I still would recommend against that. The only classes that should be marked public in any assembly are the ones that provide the public interface of that assembly. All other classes should remain an internal implementation detail of that assembly. If only because if another assembly can use these classes, eventually one will and then you are stuck keeping it public or have to make a breaking change.

So what would I recommend? That’s number three:

3. Use the InternalsVisibleTo attribute on the ActualProject assembly

With the InternalsVisibleTo assembly attribute, the .NET framework provides a very neat way of opening up classes for test while keeping them internal to their assembly.

MSDN:

The attribute is applied at the assembly level. This means that it can be included at the beginning of a source code file, or it can be included in the AssemblyInfo file in a Visual Studio project.

I prefer to go the AssemblyInfo file route. You can find the AssemblyInfo.cs file under the properties entry in your project.

Assembly info file in your project

Adding the line below will act as Ibuprofen to your “inaccessible due to its protection level” error headache.

// Friends
[assembly: InternalsVisibleTo("TestProject")]

Enjoy!

Posted in Software Development
Tags: , , , , , ,

How do I test an abstract base class if I can’t instantiate it?

You have a set of classes to write. Classes that have details specific to each, but that also have a lot in common.

You don’t like to repeat yourself and like your code DRY.

So you have created a base class to contain all the common code.

Everything is going along swimmingly. But then you hit a snag.

One or two methods are needed that would have no implementation in the base class. Instead of adding methods on the base that have no implementation, you decide to mark them abstract. Much neater and this way the code conveys that it is the responsibility of a descendant to provide the behavior of these methods (instead of relying on non-existent behavior in the base).

Marking one or more methods abstract, however, means all your tests on the base class now fail because you can’t instantiate an abstract class…

Darn.

You really don’t want to give up on this class being abstract, and you really do want to test the default behavior this class provides.

Not to worry.

If the goal is to test the abstract base class, but you can only instantiate descendants, then the answer is simple:

Define a descendant specifically intended to test the base class.

There is nothing anywhere that says you can only create descendants that will be used in production code.
There also is nothing anywhere that says that you are obliged to instantiate the exact class under test in your tests for a class.

In fact using a descendant class of the class under test is often a good way to break dependencies and provide “stubs” for methods called by the method under test.

In short, all you need to do is
– Define a descendant specifically to test the base class.
– Override the abstract methods of the base class and give them an implementation that supports your test.
– Add helper methods so you can direct it to respond as required by your tests.
– Instantiate this test descendant, but assign the instance to a variable of the base class type. This ensures that your tests can’t ever use the helper methods without using a cast.
– Only use a cast to the type of the test descendant in the “arrange” part of your tests and only to call your custom helper methods.

Posted in Software Development
Tags: , , , ,

Get your software on a string

Does your code defy every attempt to get it under control?

Sign up now and receive a regular influx of practical unit testing and software design tips to make your code more testable and improve its design. One small step at a time.
* = required field