Monday, April 22, 2019

Changing your mindset for starting TDD

This blog post was originally published on the ThoroughTest website, back when that was a thing. As a co-founder and primary content contributor for ThoroughTest, I absolutely own the rights to this post and the source code to which it refers. I intend to reproduce each blog post here on my personal blog since the company is no longer in business.

Changing the patterns and practices of developers can be a lot like herding cats, especially if they have been following a personal standard for any length of time. It can seem that the harder you try to move people in one direction forcibly, the more resistance you will face. Not only will this resistance affect morale among a team, it will also create, hopefully, figurative claw marks and scratches all over the herder. The key to adoption for any new methodology is to show the overall benefits and have a transition plan. Changing an engrained mindset takes some time, but the results can be monumental and lead to a more productive and effective development team.

Test Driven Development (TDD) is a mindset. What exactly is a mindset? Well, a mindset is a set of beliefs, assumptions, and a perspective a person has about a topic. And, how exactly is TDD a mindset then? TDD is the perspective that it’s more important to understand a problem or requirement before finding or building a solution. This is characterized by writing unit tests before writing any code to satisfy those requirements.

Most developers have the belief that it’s easier to work on the solution first and then while doing so they will begin to understand the complexities of the problem. Is this belief wrong? No, but it’s generally not the most effective. One of the major goals of TDD is to become more effective in writing code and in that effectiveness quality will increase and bugs will decrease. This reason alone is why changing to a TDD mindset will be one of the more beneficial changes a developer can make in their career.

How many times have you or another developer written code weeks, months, or even years ago that maybe was not “clean” or that you even remember ever writing? That code has now become core to the application inadvertently. Today a new developer, or even yourself, makes a change to that code to solve a different requirement. The new code solves the new problem, but now an angry user calls the support desk and says that the feature they relied on for months has stopped working.

The cycle continues of writing code to solve a new problem, break an old feature, fix the old feature, and on and on it goes. This very concern is the solution a TDD mindset will solve. It solves the issue by the codebase always knowing what the desired outcome is for any line of code written because the developer had a clear understanding of the problem before ever writing functional code. Knowing the outcome and having a test written for it helps stop the perpetual cycle of “new code breaks old code” headlines that fill up release notes.

So, the question you’ll be having now is, how do you change to a TDD mindset? It’s all fairly straightforward and the first step is that when reading any requirement or learning of any new features or functionality needed is to ask one simple question: how do I test this? Another way to phrase it is: how do I know that the code I will write is going to satisfy the requirement accurately and completely? Write this question down on a sticky note and put it on however many monitors you have: “HOW DO I TEST THIS?” It cannot be stressed enough how important this question is when changing to a TDD mindset.

The next step for a TDD mindset shift is repetition. Repetition is key here. Asking yourself the above question over and over will help engrain the notion in your mind that understanding the outcome and impact of any requirement is way more important than finding a solution first. You wouldn’t casually build a house upon dirt and then later pour concrete under it, you pour the concrete first and then build the structure from blueprints. The idea is the same in TDD. Have a solid foundation of what needs to be accomplished before ever writing code.

The final step of changing your mindset to a TDD one is probably the most important. This is the step of implementation. It doesn’t do much good to only think about implementing the principles of a TDD mindset without putting them to actual use. It takes real practice to be able to implement anything new and TDD is no different. Without constant practice of getting a requirement, completely understanding it, writing unit tests, and then writing code, it will be very difficult to truly grasp the concept.

Adoption of TDD can be hard to overcome, but by just first thinking about how something can be tested before ever writing code you will have already taken the first step. At the very least start with that question in mind and slowly work your way towards the other steps in TDD. Through time and repetition, you will be well on your way to developing a new mindset that will result in more efficient code with fewer bugs.

Sunday, April 21, 2019

Using Wrappers for Non-Fakeable Dependencies

This blog post was originally published on the ThoroughTest website, back when that was a thing. As a co-founder and primary content contributor for ThoroughTest, I absolutely own the rights to this post and the source code to which it refers. I intend to reproduce each blog post here on my personal blog since the company is no longer in business.



At the end of that post we mentioned there is a better way to test the randomness of the shuffler and we'd discuss it in a future post. Well, here's the future post where we'll discuss it.

The randomization of our shuffler is based on the use of the Random class provided by .NET. Since the Random class doesn't have an interface we can't create a fake object that represents it. That means the Random class is a non-fakeable dependency of our Shuffler class. In this particular case it isn't really a problem to just allow the Random class itself to be called because there are no side effects of such a call. Imagine if we were trying to test a method that writes a file to the operating system, though. We definitely wouldn't want to let that call happen every time our test ran because even in the best case scenario it means we have to add clean up to delete the file when the test is finished. If you consider that tests can run in parallel and test accounts on build servers often don't have I/O permissions you can easily see how it wouldn't be a good idea at all to allow new files to be created during testing.

So what do we do about it? We definitely need a way to create fake objects to use in place of these real non-fakeable objects, but how? That's where wrappers can come into play. We can create a wrapper around the non-fakeable code, inject our wrapper, and use the injected wrapper instead of the underlying code. In the earlier blog post on proof of concepts we said that one of the steps was to identify inherently non-testable code. This is why. If we know about these types of limitations before we start writing our code (and our tests) we can account for them before we do anything else so we don't have to come back and do it later.

OK, we're using Moq to create our fake, injectable Random wrapper (remember that the term "fake objects" here can refer to mocks, stubs, fakes, spies, and dummy objects). In our test we're going to want to know how many times the Random wrapper was called so we're going to want a mock object. We're not going to dive into dependency injection options right now, but we are going to inject our wrapper as a dependency.

Since we're doing test-driven development we'd add the Moq NuGet package first so we can start writing our tests. Since we're only using Moq for testing we only need to add it to the CardGames.Shuffler.Logic.Tests project.

Right now we have a unit test that checks whether the cards are shuffled by iterating through the new deck of cards and checking whether the card in each position is different than the value of the card in the same position of the original (unshuffled) deck. We also check whether the value of the card is different than the value of the card one position before and one position after the same position in the original deck. That's useful, but we had to build in a tolerance to account for the possibility that the card some cards could have ended up in the same position after shuffling that they were in before shuffling. Since shuffling is random, this is a real (albeit slim) possibility.

What we want to do is write a unit test that can check to see how many times the Random class was called. We know from our proof of concept that we should call the Next method of the Random class at least 52 times to shuffle the deck. We also know that when we call the Next method we should pass in 1 and 53 as the parameters every time. We'll call the unit test ShuffleShouldGetAtLeast52RandomNumbersBetween1And53 and all we'll do is check whether we call the Next method at least 52 times.
   1:  [TestMethod]
   2:  public void ShuffleShouldGetAtLeast52RandomNumbersBetween1And53()
   3:  {
   4:      // arrange
   5:      var randomResult = 0;
   6:      var moqRandomWrapper = new Mock<IWrapRandom>();
   7:      moqRandomWrapper.Setup(p => p.Next(It.IsAny<int>(), It.IsAny<int>()))
   8:          .Callback<int, int>((minValue, maxValue) => {
   9:              randomResult++;
  10:          }).Returns(() => randomResult);
  11:      var shuffler = new Shuffler(moqRandomWrapper.Object);
  12:   
  13:      // act
  14:      shuffler.Shuffle();
  15:   
  16:      // assert
  17:      moqRandomWrapper.Verify(p => p.Next(1, 53), Times.AtLeast(52));
  18:  }

We're using Moq to create a mock implementation of a new interface called IWrapRandom. We're then configuring Moq to spy on any calls to the Next method of our interface (we're not spying on the actual Next method of the Random class). The assertion in our test is simply to check whether we generated at least 52 random numbers. The problem at this point, of course, is that we don't actually have
an IWrapRandom interface so the code won't even compile. Let's fix that.
   1:  public interface IWrapRandom
   2:  {
   3:      void Create();
   4:   
   5:      int Next(int minValue, int maxValue);
   6:  }

Our interface is really simple because we don't need very much right now. All we need to be able to do in our test is check whether we've called the Next method at least 52 times. In order to do that we need to be able to create an instance of the Random class (void Create()) and we need to have a Next method. Now we need to modify the Shuffler class to accept an implementation of IWrapRandom in its constructor and then we'll create a private, read-only field to hold the injected implementation of IWrapRandom.
   1:  private readonly IWrapRandom _randomWrapper;
   2:   
   3:  private Shuffler(IWrapRandom randomwWrapper)
   4:  {
   5:      _randomWrapper = randomwWrapper;
   6:  }

Now that our Shuffler has an implementation of IWrapRandom we need to change our code to use it instead of the actual Random class.
   1:  public Deck Shuffle()
   2:  {
   3:      var deck = new Deck
   4:      {
   5:          Cards = new List<string>(),
   6:          IsShuffled = false
   7:      };
   8:   
   9:      while (deck.Cards.Count < 52)
  10:      {
  11:          var position = _randomWrapper.Next(1, 53);
  12:   
  13:          if (!deck.Cards.Contains(_unshuffledDeck[position]))
  14:          {
  15:              deck.Cards.Add(_unshuffledDeck[position]);
  16:          }
  17:      }
  18:   
  19:      return deck;
  20:  }

Now we're using the injected implementation of IWrapRandom in our actual code and our new test should pass. Unfortunately, when we added the constructor that accepts IWrapRandom we broke our other two tests. For the moment, go ahead and comment those tests out so we can forge ahead and make sure our latest test passes.

Once we prove that our latest test actually does pass, we need to refactor our two existing tests so they compile, then make sure that all three tests pass together. Remember that unless we change functionality intentionally, our entire test suite should always pass. Here's what our test class looks like after we refactor it.
   1:  private Mock<IWrapRandom> _moqRandomWrapper;
   2:   
   3:  [TestInitialize]
   4:  public void Setup()
   5:  {
   6:      _moqRandomWrapper = new Mock<IWrapRandom>();
   7:   
   8:      var random = new Random();
   9:      _moqRandomWrapper.Setup(p => p.Next(It.IsAny<int>(), It.IsAny<int>()))
  10:          .Returns(() => random.Next(1, 53));
  11:  }

We added a new method called Setup that will run before each test in this test class. This allows us to reconfigure the mock of IWrapRandom before each test executes. We're setting up our mock object to use the actual Random class to generate and return random numbers. We have to do this so that our tests pass. If we don't configure the mock object to return a number then our code will fail when it tries to get the card from the unshuffled deck.
   1:  [TestMethod]
   2:  public void ShuffleShouldMoveAces()
   3:  {
   4:      // arrange
   5:      var shuffler = new Shuffler(_moqRandomWrapper.Object);
   6:   
   7:      // act
   8:      var deck = shuffler.Shuffle();
   9:   
  10:      // assert 
  11:      Assert.AreNotEqual("AH", deck.Cards[0]);
  12:      Assert.AreNotEqual("AD", deck.Cards[13]);
  13:      Assert.AreNotEqual("AC", deck.Cards[26]);
  14:      Assert.AreNotEqual("AS", deck.Cards[39]);
  15:  }

   1:  [TestMethod]
   2:  public void ShuffleShouldRandomizeADeckOfCards()
   3:  {
   4:      // arrange
   5:      var unshuffledDeck = new List<string>
   6:      {
   7:          "AH", "2H", "3H", "4H", "5H", "6H", "7H", "8H", "9H", "10H",
   8:          "JH", "QH", "KH", "AD", "2D", "3D", "4D", "5D", "6D", "7D",
   9:          "8D", "9D", "10D", "JD", "QD", "KD", "AC", "2C", "3C", "4C",
  10:          "5C", "6C", "7C", "8C", "9C", "10C", "JC", "QC", "KC", "AS",
  11:          "2S", "3S", "4S", "5S", "6S", "7S", "8S", "9S", "10S", "JS",
  12:          "QS", "KS"
  13:      };
  14:      var shuffler = new Shuffler(_moqRandomWrapper.Object);
  15:   
  16:      // act
  17:      var deck = shuffler.Shuffle();
  18:   
  19:      // assert
  20:      var numberOfMatches = 0;
  21:      for (var i = 0; i < 52; i++)
  22:      {
  23:          if (unshuffledDeck[i] == deck.Cards[i] ||
  24:              (i > 0 && deck.Cards[i - 1] == unshuffledDeck[i]) ||
  25:              (i < 51 && deck.Cards[i + 1] == unshuffledDeck[i]))
  26:          {
  27:              numberOfMatches++;
  28:          }
  29:      }
  30:      Assert.IsTrue(numberOfMatches < 5,
  31:          $"{numberOfMatches} is not less than 5");
  32:  }

We need to modify the existing tests to inject the mock implementation of IWrapRandom in our constructor.
   1:  [TestMethod]
   2:  public void ShuffleShouldGetAtLeast52RandomNumbersBetween1And53()
   3:  {
   4:      // arrange
   5:      var shuffler = new Shuffler(_moqRandomWrapper.Object);
   6:   
   7:      // act
   8:      shuffler.Shuffle();
   9:   
  10:      // assert
  11:      _moqRandomWrapper.Verify(p => p.Next(1, 53), Times.AtLeast(52));
  12:  }

Finally, we refactor our new test to stop creating a new mock of IWrapRandom and just go ahead and inject the one we're creating in the Setup method (which, remember, is already configured so we don't have to do it again here).

At this point our tests are successful, but if we were to actually run our code we'd have issues. That's because we haven't written an actual implementation of the IWrapRandom interface. We need to specify what should happen during a normal execution of our program. This is an important part of creating wrappers: our wrappers should wrap the smallest amount of code possible. Our real implementation of IWrapRandom looks like this.
   1:  public class RandomWrapper : IWrapRandom
   2:  {
   3:      private Random _random;
   4:   
   5:      public void Create()
   6:      {
   7:          _random = new Random();
   8:      }
   9:   
  10:      public int Next(int minValue, int maxValue)
  11:      {
  12:          return _random.Next(minValue, maxValue);
  13:      }
  14:  }

We don't want to put any logic in our methods because we can't test whatever logic we do put in there. Since the whole point of writing the wrapper in the first place was to be able to test whether and how many times the Next method was called, it wouldn't make sense to then put non-testable code in the implementation of the wrapper. Again, this is a really important part of wrappers. Try to keep your wrapper method focused on wrapping a single method of a non-fakeable dependency (the Next method of our wrapper only wraps the Next method of the built-in Random class).

Ideally, all code would be fakeable, but we don't code in an ideal world so sometimes we need to make small changes like this so we can verify our code works the way it's supposed to at all times.

Saturday, April 20, 2019

Test-Driven Development on Proof of Concepts

This blog post was originally published on the ThoroughTest website, back when that was a thing. As a co-founder and primary content contributor for ThoroughTest, I absolutely own the rights to this post and the source code to which it refers. I intend to reproduce each blog post here on my personal blog since the company is no longer in business.


Every developer knows there are times when you just have to play around with some code to see what works and what doesn't. Proof of concept code can be a valuable tool when you're learning something new, trying to figure out a new library, or a plethora of other reasons. Once you've written your proof of concept and it's time to turn into real, quality-driven code, how do you make the transition? This comes up a lot for us so we'll walk you through a few steps that will make sure your proof of concept can seamlessly transition to a test-driven application.

The first thing you'll want to do is take your proof of concept and really look at what it's doing. Think of it like a car: you know it runs, but now you need to really inspect how it runs. You need to look at each individual piece and figure out how they function.

Once you know how the concept code works you'll want to identify any areas that aren't inherently unit-testable. Let's say your proof of concept uses a packaged set of assemblies from a vendor that weren't written to be mocked, spied, etc. You'll want to identify those pieces before you try to start unit testing or it might be bad news later.

Next you'll want to generate some really loose technical requirements. We know, you thought technical requirements were a thing of the past (waterfall, anyone?), but they are sometimes still useful. This is one of those situations. Don't get too specific with them and don't spend a lot of time writing them. Just jot down what's happening in your proof of concept code now so you'll know what tests to write in a few minutes.

At this point you have a working proof of concept, a thorough understanding of how it's working, an awareness of which parts aren't unit-testable, and some really rough technical requirements. You're ready to start your real code now. From this point on you basically get to approach your test-driven process the same way you would if you had not created a proof of concept first. You'll write your tests based on your requirements, write just enough code so the tests can pass, then refactor the code (and the tests) until it all makes you happy. How about an example?

Our feature is a full-fledged card game suite. We ultimately want to have multiple games available where the user can choose which game to play, how much he wants to wager (just for fun!), how many decks of cards to use, and a few other options. The first step is figuring out how to effectively shuffle a deck of cards. No matter what we decide to do with any of the card games, if we can't shuffle the cards we won't create a positive experience for our users. For this sprint (we're agile), one of the stories our team has taken on is developing the card shuffling mechanism that will be used by all of the card games in the future. We decided to write a proof of concept to make sure we have a really solid idea of how we're going to do this (and whether it's even possible) before we start writing our tests and our code.

Now, we want to specify right up front that this isn't necessarily the best way to do this. We're showing how to do it because we know that we don't always get to do things the best way. In those cases we have to accept what we've been given and make the best of it, which is what we're about to do.

Here's what our proof of concept looks like right now:
   1:  public void Shuffle()
   2:  {
   3:      var deck = new Deck { Cards = new List<string>(), IsShuffled = false };
   4:  
   5:      while (deck.Cards.Count < 52)
   6:      {
   7:          var random = new Random();
   8:          var position = random.Next(1, 53);
   9:  
   10:         if (!deck.Cards.Contains(_deck[position]))
   11:         {
   12:             deck.Cards.Add(_deck[position]);
   13:         }
   14:     }
   15: 
   16:     deck.Cards.ForEach(Console.WriteLine);
   17: }

Now we want to go through our process so we can use test-driven development to build the releaseable, reusable shuffle code.
  1. Figure out how everything works
    This is a pretty easy one since our proof of concept code is so simple and small
  2. Identify areas that aren't inherently unit-testable
    We're using the System.Random class, which doesn't have an interface that we can mock so we'll have to do something about that.
    We're not going to cover how to mock this class in this post, but we'll get into it in the future
  3. Generate loose technical requirements
    1. Create an empty deck of cards
    2. Repeat steps 3 and 4 until the new deck is populated with 52 cards
    3. Generate a random number
    4. Put the card represented by the random number into the new deck if it isn't already in there
So now we know what's happening in our proof of concept and we can identify what tests we should write, at least for this part of our shuffler. We generated those technical requirements just so we'd really know what our proof of concept is doing, and therefore what our actual code should do. We don't necessarily need to write a separate unit test for each requirement we generated. In fact, we generally shouldn't write one test per acceptance criterion or requirement.

In this case we can probably get away with writing a unit test called ShuffleShouldRandomizeADeckOfCards. This test will check that after we call the Shuffle method we have a deck of cards that is not in consecutive order. Easy enough.
   1:  [TestMethod]
   2:  public void ShuffleShouldRandomizeADeckOfCards()
   3:  {
   4:      // arrange
   5:      var shuffler = new Shuffler();
   6:   
   7:      // act
   8:      var deck = shuffler.Shuffle();
   9:   
  10:      // assert 
  11:      Assert.AreNotEqual("AH", deck.Cards[0]);
  12:  }

Depending on what our rules are for testing and what our team thinks, this might be good enough. We also might go with something like this:
   1:  [TestMethod]
   2:  public void ShuffleShouldRandomizeADeckOfCards()
   3:  {
   4:      // arrange
   5:      var shuffler = new Shuffler();
   6:   
   7:      // act
   8:      var deck = shuffler.Shuffle();
   9:   
  10:      // assert 
  11:      Assert.AreNotEqual("AH", deck.Cards[0]);
  12:      Assert.AreNotEqual("AD", deck.Cards[13]);
  13:      Assert.AreNotEqual("AC", deck.Cards[26]);
  14:      Assert.AreNotEqual("AS", deck.Cards[39]);
  15:  }

We can make multiple assertions in a single unit test because we're ultimately testing the same thing: whether the deck is shuffled. Remember that at this point our code still looks like this:
   1:  public Deck Shuffle()
   2:  {
   3:      throw new NotImplementedException();
   4:  }

When our test runs, it will fail. Of course it will, we're not doing anything yet! Since we've achieved a red test, we need to make our test turn green.
   1:  public Deck Shuffle()
   2:  {
   3:      var deck = new Deck
   4:      {
   5:          Cards = new List<string>()
   6:      };
   7:   
   8:      deck.Cards.AddRange(new List<string> { "AS", "2S", "3S", "4S", "5S", 
               "6S", "7S", "8S", "9S", "10S", "JS", "QS", "KS" });
   9:      deck.Cards.AddRange(new List<string> { "AC", "2C", "3C", "4C", "5C", 
               "6C", "7C", "8C", "9C", "10C", "JC", "QC", "KC" });
  10:      deck.Cards.AddRange(new List<string> { "AD", "2D", "3D", "4D", "5D", 
               "6D", "7D", "8D", "9D", "10D", "JD", "QD", "KD" });
  11:      deck.Cards.AddRange(new List<string> { "AH", "2H", "3H", "4H", "5H", 
               "6H", "7H", "8H", "9H", "10H", "JH", "QH", "KH" });
  12:   
  13:      return deck;
  14:  }

Now our test passes, but this code isn't shuffling anything. This is probably the hardest part of doing TDD when you already have a proof of concept. We did the proof of concept so we'd know how to do what we want to do, but now we're essentially pretending that we don't know what we want to do. This is tricky, but it's important because by writing this code to turn our test green we've proven that our test isn't very effective. We're going to need some better tests, but remember that our tests shouldn't be more complicated than our code. We'll leave that first test in there for now since we know it passes and we'll add some additional tests, but we need to rename the test since it isn't really checking what the name says. Let's rename it to ShuffleShouldMoveAces. It's not a great name, but it's more descriptive of what's actually going on.

Now we can create another test named ShuffleShouldRandomizeADeckOfCards and do a more extensive check of the randomness of our deck of cards.
   1:  [TestMethod]
   2:  public void ShuffleShouldRandomizeADeckOfCards()
   3:  {
   4:      // arrange
   5:      var unshuffledDeck = new List<string>
   6:      {
   7:          "AH", "2H", "3H", "4H", "5H", "6H", "7H", "8H", "9H", "10H",
   8:          "JH", "QH", "KH", "AD", "2D", "3D", "4D", "5D", "6D", "7D",
   9:          "8D", "9D", "10D", "JD", "QD", "KD", "AC", "2C", "3C", "4C",
  10:          "5C", "6C", "7C", "8C", "9C", "10C", "JC", "QC", "KC", "AS",
  11:          "2S", "3S", "4S", "5S", "6S", "7S", "8S", "9S", "10S", "JS",
  12:          "QS", "KS"
  13:      };
  14:      var shuffler = new Shuffler();
  15:   
  16:      // act
  17:      var deck = shuffler.Shuffle();
  18:   
  19:      // assert
  20:      var numberOfMatches = 0;
  21:      for (var i = 0; i < 52; i++)
  22:      {
  23:          if (unshuffledDeck[i] == deck.Cards[i] ||
  24:              (i > 0 && deck.Cards[i-1] == unshuffledDeck[i]) || 
  25:              (i < 51 && deck.Cards[i + 1] == unshuffledDeck[i]))
  26:          {
  27:              numberOfMatches++;
  28:          }
  29:      }
  30:      Assert.IsTrue(numberOfMatches < 5,
  31:          $"{numberOfMatches} is not less than 5");
  32:  }


What we're doing here is checking whether each card in the shuffled deck is different than the card in the same position as the unshuffled deck, or the position just before it, or the position just after it. Since we know it's theoretically possible for a shuffled card to end up in the same spot in the deck, we've allowed that to happen with up to four cards and still have a passing test. With the code we have right now, this test fails. Now we can implement our proof of concept code to get make it green.
   1:  private readonly Dictionary<int, string> _unshuffledDeck =
   2:              new Dictionary<int, string>
   3:  {
   4:      {1, "AH"}, {2, "2H"}, {3, "3H"}, {4, "4H"}, {5, "5H"},
   5:      { 6, "6H"}, {7, "7H"}, {8, "8H"}, {9, "9H"}, {10, "10H"},
   6:      { 11, "JH"}, {12, "QH"}, {13, "KH"}, {14, "AD"}, {15, "2D"},
   7:      { 16, "3D"}, {17, "4D"}, {18, "5D"}, {19, "6D"}, {20, "7D"},
   8:      { 21, "8D"}, {22, "9D"}, {23, "10D"}, {24, "JD"}, {25, "QD"},
   9:      { 26, "KD"}, {27, "AC"}, {28, "2C"}, {29, "3C"}, {30, "4C"},
  10:      { 31, "5C"}, {32, "6C"}, {33, "7C"}, {34, "8C"}, {35, "9C"},
  11:      { 36, "10C"}, {37, "JC"}, {38, "QC"}, {39, "KC"}, {40, "AS"},
  12:      { 41, "2S"}, {42, "3S"}, {43, "4S"}, {44, "5S"}, {45, "6S"},
  13:      { 46, "7S"}, {47, "8S"}, {48, "9S"}, {49, "10S"}, {50, "JS"},
  14:      { 51, "QS"}, {52, "KS"}
  15:  };
  16:   
  17:  public Deck Shuffle()
  18:  {
  19:      var deck = new Deck
  20:      {
  21:          Cards = new List<string>(),
  22:          IsShuffled = false
  23:      };
  24:   
  25:      while (deck.Cards.Count < 52)
  26:      {
  27:          var random = new Random();
  28:          var position = random.Next(1, 53);
  29:   
  30:          if (!deck.Cards.Contains(_unshuffledDeck[position]))
  31:          {
  32:              deck.Cards.Add(_unshuffledDeck[position]);
  33:          }
  34:      }
  35:   
  36:      return deck;
  37:  }


And there we have it*. We took proof of concept code and ended up doing test-driven development with it.

* There is actually a better way to test the randomness of our Shuffle method, but we're going to cover that in a future blog post about the use of wrappers.

Thursday, April 11, 2019

Securing an Endpoint with an API Key

I've used API keys to access various 3rd party APIs in the past, but until recently I hadn't ever secured my own endpoint with an API key. Don't get me wrong, I've secured my endpoints in the past, just usually through the use of the [Authorize] attribute in .NET. Recently I encountered a situation where we needed to call an endpoint from an integration (SSIS) package that didn't have the opportunity to log in first. It quickly became obvious to us that the solution was to secure that particular endpoint in a different way. And here we are. This wasn't a difficult process, but it was kind of frustrating and it was actually pretty fun to implement so I wanted to keep track of the solution. Also, it's been a really long time since I posted so I figured it was time.

There are two parts to the solution. The first part - the caller (in our case an SSIS package, but it could be anything) - builds the API key and sends the request. The second part - the receiver (in our case a Web API endpoint) - receives the request and checks it for validity. There are a few things we considered when developing this solution.
  1. We needed to only allow requests from specific callers
  2. We needed to protect against replay attacks
  3. We needed to convey additional information in the request
After doing some research we came across Hash-based Message Authentication Code (HMAC) Authentication. It's basically a method for guaranteeing the information in the request via the use of an authentication header. (For more information on HMAC there's a pretty good blog post here.) There may be libraries out there to do this for us, but we couldn't find one we liked so we decided to roll our own.

Our HMAC Authentication header is going to have four parts to it: the ID of the caller, a time stamp, a random nonce value (a GUID), and the hashed (MD5), serialized (into JSON) content that we're sending to the server. The "content" here is the additional information we need to convey that I mentioned above.

The Caller

The first thing we do when creating the request is generate our content. In our particular case we're going to serialize, hash, and encode the content so that it can be included in the query string.
   1:  public string GenerateContent(string email, int id, string name)
   2:  {
   3:      var content = new SomeContent
   4:      {
   5:          Email = email,
   6:          Id = id,
   7:          Name = name
   8:      };
   9:  
   10:     var json = JsonConvert.SerializeObject(content);
   11: 
   12:     string contentAsBase64String;
   13:     using (var md5 = MD5.Create())
   14:     {
   15:         var encodedContent = Encoding.ASCII.GetBytes(json);
   16:         var md5Hash = md5.ComputeHash(encodedContent);
   17:         contentAsBase64String = Convert.ToBase64String(md5Hash);
   18:     }
   19: 
   20:     return contentAsBase64String;
   21: }


Now that we have the hashed, encoded contents that we're going to send to the endpoint we can build the full hmac header value. That's pretty easy with string interpolation.
   1:  var applicationId = "unicorns-and-puppies";
   2:  var timeStamp = DateTime.UtcNow;
   3:  var nonce = Guid.NewGuid();
   4:  var authenticationKey = $"{applicationId};{timeStamp.ToString("s")};{nonce};{contentAsBase64String}";


At this point we're going to create the request and add everything in as an authorization header. I'm including all of that code here, even though the mechanism for creating the request and adding the header can vary depending on which version of .Net you're using and any 3rd party libraries you might include.
   1:  var client = new HttpClient();
   2:  
   3:  var secretAsBase64 = Convert.FromBase64String("Some Randomly Generated String");
   4:  string hashedAuthenticationKey;
   5:  using (var hmac = HMACSHA512(secretAsBase64))
   6:  {
   7:      var authenticationKeyBytes = Encoding.UTF8.GetBytes(authenticationKey);
   8:      var hashedAuthenticationKey = hmac.ComputeHash(authenticationKeyBytes);
   9:      hashedAuthenticationKeyAsBase64String = Convert.ToBase64String(hashedAuthenticationKey);
   10: }
   11: 
   12: client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("hmac", authenticationKey);


We've added the header and now we want to create our body. What we're doing here is passing in the body with the content we want to pass in, and with the API key that we created just above. When the API receives the request we'll rebuild the API key and compare it to what's in the body here.

   1:  var body = new SomeRequest;
   2:  {
   3:      ApiKey = hashedAuthenticationKeyAsBase64String,
   4:      Content = json
   5:  };


And finally we can send the request.
   1:  var httpContent = new StringContent(JsonConvert.SerializeObject(body), Encoding.UTF8, "application/json");
   2:  
   3:  client.PostAsync("https://remote-endpoint.com/api/endpoint", httpContent);

The Endpoint

Now that we've sent the request, we have to receive it and validate it. When a .Net API receives a request there are different ways we can retrieve the data from the request. One common way is to use the FromBody and FromQuery attributes in the call signature. There's another attribute we're going to use to get the header, called FromHeader.

We'll get the body and the authorization header separately, validate the header pieces individually, then build the expected key the same way we did in the calling system and compare the expected key to the actual key to make sure they match.

   1:  public IActionResult Send([FromBody]SomeRequest something, [FromHeader(Name = "authorization")] string auth)
   2:  {
   3:      // check whether an authorization header exists
   4:  
   5:      var authorizationHeaderParts = authorizationHeader.Split(' ');
   6:      if (!authorizationHeader[0].Equals("hmac", StringComparison.OrdinalIgnoreCase))
   7:      {
   8:          // invalid request
   9:      }
   10: 
   11:     var authorizationPieces = authorizationHeaderParts[1].Split(';');
   12: 
   13:     if (authorizationPieces.Length != 4)
   14:     {
   15:         // invalid request
   16:     }
   17: 
   18:     // check whether authorizationPieces[0] is a valid application sending the request
   19: 
   20:     if ((DateTime.UtcNow - Convert.ToDateTime(authorizationPieces[1])).Seconds > 10)// we want the request to have been created less than 10 seconds ago to protect against replay attacks, but this length is arbitrary and could be lengthened or shortened based on need
   21:     {
   22:         // invalid request
   23:     }
   24: 
   25:     var applicationId = authorizationPieces[0];
   26:     var timestamp = authorizationPieces[1];
   27:     var nonce = authorizationPieces[2];
   28:     string contentAsBase64String;
   29:     using (var md5 = MD5.Create())
   30:     {
   31:         var content = Encoding.ASCII.GetBytes(something.Content);
   32:         var md5Hash = md5.ComputeHash(content);
   33:        contentAsBase64String = Convert.ToBase64String(md5Hash);
   34:     }
   35: 
   36:     if (!contentAsBase64String.Equals(authorizationPieces[3]))
   37:     {
   38:         // invalid request
   39:     }
   40: 
   41:     var authenticationKey = $"{applicationId};{timestamp};{nonce};{contentAsBase64String}";
   42: 
   43:     var secretAsBase64 = Convert.FromBase64String("Some Randomly Generated String");
   44: 
   45:     string hashedAuthenticationKeyAsBase64String;
   46:     using (var hmac = new HMACSHA512(secretAsBase64))
   47:     {
   48:         var authenticationKeyBytes = Encoding.UTF8.GetBytes(authenticationKey);
   49:         hashedAuthenticationKeyAsBase64String = Convert.ToBase64String(hashedAuthenticationKey);
   50:     }
   51:     if (!hashedAuthenticationKeyAsBase64String.Equals(something.ApiKey))
   52:     {
   53:         // invalid request
   54:     }


That's it! We created a request protected with an API key and then accepted the request and validated the API key. After looking this over again so I could post this entry I realize that it's probably more convoluted than it really needs to be. I think in the future if I have to do this again I'll use this code as the starting point, but definitely see where I can streamline it.

Monday, November 26, 2018

Using Assert.Throws and Assert.ThrowsAsync with XUnit

I keep having to dig through my old code to find instances where I've tested particular attributes about an exception being thrown. XUnit has a couple of methods that allow you to check exceptions, but I always forget exactly how they're used. Since that's pretty much what this blog is for, here it is.

The first one (
Assert.Throws
) is pretty straightforward. It accepts a parameter of type
Func<object>
that should basically be a call to the method you want to test. Let's say you want to test a method called CheckMyName in a controller called WhoController. That might look like this:
Assert.Throws<CustomException>(() => _whoController.CheckMyName());

All that test is doing is checking that when your method is called it throws an instance of CustomException (presumably you've set up the test so that something in CheckMyName causes an exception to be thrown). You can always get access to the instance of CustomException that was thrown by using the result of Throws, which - because it is generic - will be an instance of whatever type you specified (in this case, CustomException).
var actual = Assert.Throws<CustomException>(() => _whoController.CheckMyName());

Once you have the instance of CustomException you can examine individual properties or whatever else you want to do with it.


The other method provided by XUnit is for testing asynchronous methods;
Assert.ThrowsAsync<T>
. I always get screwed up with this one because of async/await and when I should use what. Assuming my test uses async (i.e. public async Task MyTestShouldDoSomething()) where do I put the await? That's would look like this:
var actual = await Assert.ThrowsAsync<CustomException>(async () => await _whoController.CheckMyName());

It seems a little tricksy, but that's how you do it. Or, at least, that's how I do it and it works. It's possible I'm using it wrong, but I know that it definitely works so I'm fine with it.

Tuesday, October 30, 2018

Find a Stored Procedure By Searching Its Contents

Today I had to do something for the first time in a while and it took me a moment to remember the syntax so I figured I'd better write a post about it so that doesn't happen again. In SQL Server you can search the contents of a stored procedure. This is useful when you're trying to figure out which stored procedure(s) update(s) a particular field, for example. I'm sure there are other uses, but I want to keep this as short as possible.

Basically what you can do is use the built-in sys tables to search the text (contents) of a stored procedure. It's pretty straightforward so I'll just get right to the code. This simple SQL statement will get the names of any stored procedures that use the field "CurrentMarriageStatus".
SELECT DISTINCT so.[name] FROM sysobjects so INNER JOIN syscomments sc ON so.id = sc.id WHERE sc.[text] LIKE '%CurrentMarriageStatus%'


That's it! Then you can take the results and go through them one at a time to see how they're using the field you searched for.

Friday, October 5, 2018

Git: Forcing Local to Match Remote

Every now and then I've found myself making changes directly on a branch that can't be updated from local to remote. Let's say we have the "master" branch and from that we create the "working" branch. It is impossible (by rules) to update "master" directly. Instead, we must create a pull request so that our code may be reviewed. But sometimes I've already done the work on "master", committed my changes locally on "master" and tried to push them to the remote repository. That, of course, leads to an error message along the lines of "Pushes to this branch are not permitted; you must use a pull request to update this branch." That's exactly the error message we want to see, but now I'm stuck with code in the wrong branch and my "master" doesn't match the remote "master". Here's the super easy way to fix that.

git fetch --prune
git checkout -b new-branch-with-my-changes
git push --set-upstream origin new-branch-with-my-changes
git checkout master
git reset --hard origin/master

These simple steps will 1) create a new branch called new-branch-with-my-changes on the local and remote repositories, and 2) overwrite the local master branch to match the remote master branch.

Super simple, but I always have to Google it so now it's here for future me to find it more easily next time.