Showing posts with label C#. Show all posts
Showing posts with label C#. Show all posts

Tuesday, August 11, 2026

"New" C# Goodies

I've been working with C# almost since it was first released, which has led me to keep using some things I learned way back then even though there are easier ways to do those same things now. This will probably be a series of posts that - if anyone is actually reading these - may cause readers to question my own development capabilities. All I can say is: some day it'll happen to you, too.

Anyway, today I learned about the "Index from end operator" that became available in C# 8.0. It's used like this: var item = list[^1]; and simply counts the collection from the end instead of the beginning, so ^1 just means "get me the first item from the collection, but start counting from the end". It's a simpler form of var item = list[list.Count - 1];

Much easier to write and read once you know it's available. 

Thursday, July 16, 2026

Converting RGBA to Hex

I had the displeasure recently of needing to generate HTML that would eventually be exported/saved as a .docx (Word) document. Part of the source of the HTML was a rich text editor and something along the path was converting my specified hex color values (#fff, etc.) into their rgba equivalents. The problem is that Word (which sucks with HTML) doesn't recognize rgba values so I really needed those to stay hex. It turns out you can just write a method for that. Well, Claude can. I can't. But I can copy Claude's method and understand it. Which I did. Here it is.

private static readonly Regex RgbRegex = new(@"rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*[\d.]+\s*)?\)", RegexOptions.Compiled | RegexOptions.IgnoreCase);

private static string ConvertRgbToHex(string style) { return RgbRegex.Replace(style, m => { int r = int.Parse(m.Groups[1].Value); int g = int.Parse(m.Groups[2].Value); int b = int.Parse(m.Groups[3].Value); return $"#{r:X2}{g:X2}{b:X2}"; }); }
I just make sure the HTML runs through their during save and my hex values persist. Beautiful.

Thursday, December 9, 2021

Linq DistinctBy

I've had to search for this quite a few times so I figured it was probably time to write it up. I actually did find this answer somewhere else (here, if you're interested) and modified it only slightly to follow my standards.

As I often (somehow) forget, the default .Distinct() extension in System.Linq for an IEnumerable just checks to see if objects are the exact same as each other. You may recall in C# that being the exact same means the two objects are actually references to the same exact object. I can say with a good amount of confidence that in 16+ years of working in C# that's never actually been what I'm trying to do when I use .Distinct(). I'd say my most common usage is determining whether two objects have the same data on them - usually one specific field (like an ID field, for example). There are Stack Overflow posts and extension libraries out there that include this, but I'm pretty loathe to bring in a whole library for one simple extension method. Which brings us to today.

I'm using Dapper to get a list of objects from the database and then using the splitOn feature to get the children of those objects. Think of a teacher and students: I'm getting all the teachers in the school and then all of each teacher's students in a single query, then I want to break the students out according to their teachers by using the splitOn feature of Dapper. That's no problem and doesn't even require me to use .Distinct(). If I also include the clubs that each teacher oversees, I could easily end up with duplicate students in my results. The easiest way to get the distinct students in my results would be to use the .Distinct() extension method included in System.Linq, if only that worked the way it seems like it should. Instead, I'll have to write my own. So here we are.


   1: public static IEnumerable<T> DistinctBy<T>(this IEnumerable<T> list, Func<T, object> propertySelector) where T : class
   2: {
   3:   return list.GroupBy(propertySelector).Select(x => x.First());
   4: }

That's it, really. The somewhat obvious flaw is that we'll take the first match we find, but if you're looking for distinct objects, that really shouldn't be too big of a deal. Hopefully this helps you (even if "you" are really just future me).

Thursday, September 12, 2019

Converting Strings to Enums

In my last post I showed how to use the DescriptionAttribute to specify a customized value for an Enum value and I promised to show how to convert back to an Enum. Here it is, the FromDescription string extension method. This time I did remember to get the link from the SO answer I got this from. Thanks, max!
   1: public static T FromDescription(this string description)
   2: {
   3:   var type = typeof(T;
   4:   if (!type.IsEnum)
   5:   {
   6:     throw new InvalidOperationException($"{description} does not match any of the enumeration values);
   7:   }
   8: 
   9:   foreach (var field in type.GetFields())
  10:   {
  11:     if (Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute)) is DescriptionAttribute attribute)
  12:     {
  13:       if (attribute.Description == description)
  14:       {
  15:         return (T)field.GetValue(null);
  16:       }
  17:     }
  18:     else
  19:     {
  20:       if (field.Name == description)
  21:       {
  22:         return (T)field.GetValue(null);
  23:       }
  24:     }
  25:   }
  26: 
  27:   throw new InvalidOperationException($"{description} does not match any of the enumeration values);
  28: }

Now that we have the extension method we can invoke it on any string, like this:
var contactType = "Phone Call".FromDescription<ContactTypes>();

Wednesday, September 11, 2019

Converting Enums to Strings

Yes, I'm aware you can easily get the string value of an Enum by using .ToString(). And that's great in many circumstances. I recently came across one where it was important to us to be able to translate an Enum to a custom string that included spaces (which you can't do with an Enum's value). I should have bookmarked the SO answer where I got this code from, but I didn't (sorry, Original Author, whoever you are!).

This extension method takes advantage of the built-in DescriptionAttribute. We decorate our Enum values with the DescriptionAttribute and provide whatever we want, like this:
   1: public enum ContactTypes
   2: {
   3:   [Description("Phone Call")]
   4:   Phone,
   5:   Email,
   6:   Chat
   7: }

Once we've decorated the Enum values, we'll need the extension method to get the description we just provided.
   1: public static string ToDescription(this Enum value)
   2: {
   3:   var da = (DescriptionAttribute[]) value.GetType().GetField(value.ToString()).GetCustomAttributes(typeof(DescriptionAttribute), false);
   4: 
   5:   return da.Length > 0 ? da[0].Description : value.ToString();
   6: }

Now we just need to use the extension method on our Enum to get the description we specified. Let's say we have a class that looks like this:
   1: public class Interaction
   2: {
   3:   public string UserName { get; set; }
   4: 
   5:   public ContactTypes ContactType { get; set; }
   6: }

If we wanted to get "Phone Call", "Email", and "Chat" returned (depending on which one was assigned in the class), we'd use the ToDescription extension method like this:
   1: var contact = new Interaction { ContactType = ContactTypes.Phone, UserName = "engineer-andrew" };
   2: var contactType = contact.ContactType.ToDescription();

Since we didn't use the DescriptionAttribute on Chat and Email, they'll default to just use .ToString() so they'd return "Chat" and "Email", respectively.
That's all there is to it. I know it's kinda simple, but I've used it a couple of times and my rule is to blog about those things. In the next post I'll show how to go the other way (take a string and find its matching Enum value).

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.

Thursday, July 20, 2017

Unit Testing Web API when the Result is an Anonymous Object

Sometimes it seems like each day opens my eyes to some new challenge or trick.  If only I could find the time to write about them all.  Today I discovered you can return anonymous objects from a WebAPI controller.  Returning the data was actually the easy part, but being able to unit test it turned out to be a little bit tricky.

I found this answer on Stack Overflow, which pointed to this blog post by Patrick Desjardins that ultimately helped me figure out what needed to be done, but I wanted to document the actual steps I took to make this all work.

The scenario was that we had a custom object that had a bunch of properties on it.  Our UI needed all of that information plus one more field, but we weren't able to just add another property to our object because reasons (that part isn't important).  We also didn't want to create a brand new object to contain our original object plus this other field.  The obvious solution was to return an anonymous type from our controller.

Let's say our object is book and it has a couple of properties on it.  It looks like this:

   1:  public class Book
   2:  {
   3:      public string Author { get; set; }
   4:          
   5:      public string ISBN { get; set; }
   6:  }

When we return our object to the UI we also need to include a StoreId.  What we want to return will look like this:
{
  StoreId: 12345,
  Book: {
    Author: "Herman Melville"
        
    ISBN: "978-1853260087"
  }
}

What we ended up with was a controller method that looks like this:
   1:  [HttpGet]
   2:  public async Task<IHttpActionResult> GetBook()
   3:  {
   4:      var book = new Book
   5:      {
   6:          Author = "Herman Melville",
   7:          ISBN = "978-1853260087"
   8:      };
   9:   
  10:      var result = new {StoreId = 12345, Book = book};
  11:      return Ok(result);
  12:  }

In order to test this we have to do two things.  For starters let's say our Web API project is called Bookstore.Api and our unit tests are in a separate project called Bookstore.Api.UnitTests.  We need to modify the AssemblyInfo.cs file in Bookstore.Api to make internal types available to Bookstore.Api.UnitTests because the anonymous object we're returning from the GetBook method becomes an internal type when it's created.  To do this, just open AssemblyInfo.cs in Bookstore.Api and add this line (where it gets added doesn't seem to matter, but the name absolutely does matter):
[assembly: InternalsVisibleTo("Bookstore.Api.UnitTests")]

Important Note: In .Net Core 2.0 (at least) you have to create the AssemblyInfo.cs file manually as it is no longer generated automatically when you create the file. I just expanded the Properties folder, right-clicked > Add > Class > AssemblyInfo.cs and added the above attribute as the only thing in the file. I did have to include the using statement for System.Runtime.CompilerServices as well.

Finally we can write our test to check the return value of the StoreId in our unit test:
   1:  [TestMethod]
   2:  public async Task GetBookShouldReturnStoreIdWithBook()
   3:  {
   4:      dynamic result = await bookController.GetBook();
   5:   
   6:      Assert.AreEqual(12345, result.Content.StoreId);
   7:  }

It's really important to use dynamic as the return type (as much as I hate doing that) because it's the only way the compiler won't make angry faces at you.  I hope this helps someone (or future me).

Thursday, December 1, 2016

Testing a Request in an ApiController

I recently came across a situation where I needed to test an action method on an ApiController to make sure the correct response was returned to the user based on the request.  In this particular case I was testing the ability to upload a file to an API and I needed to return a 400 (Bad Request) error if the content type of the request was not right.  I knew the code was working (I know, it wasn't TDD, but sometimes you have to roll with the punches), but I was having a hard time testing it.  To make things worse I couldn't use shims or fakes because the build server kept blowing up on them.  Fortunately, I came across a couple of really helpful blogs that pointed me in the right direction.

First, Shiju Varghese's blog on writing unit tests for an ApiController.  Next I used William Hallat's blog on testing a file upload to finish things off.

What I ended up with is pretty neat and easy to use, customized to meet my needs.  As usual, I'm posting it here so I don't have to redo the work next time.

The first key to making this work is declaring the controller.  Let's just say that our controller has a single object injected, an ILogger (a fairly common practice).  Instead of just doing this:
var controller = new ExampleController(_moqLogger.Object);

We want to do this:
   1:  var controller = new ExampleController(_moqLogger.Object)
   2:  {
   3:      Request = new HttpRequestMessage
   4:      {
   5:          Content = new ObjectContent(typeof(string), null, new JsonMediaTypeFormatter()),
   6:          Method = HttpMethod.Post
   7:      }
   8:  };

UPDATE: We actually also want to include an HttpConfiguration to prevent another error I was getting later:
   1:  var request = new HttpRequestMessage
   2:  {
   3:      Content = new ObjectContent(typeof(string), null, new JsonMediaTypeFormatter()),
   4:      Method = HttpMethod.Post
   5:  };
   6:  request.Properties.Add(HttpPropertyKeys.HttpConfigurationKey, new HttpConfiguration());
   7:  var controller = new ExampleController(_moqLogger.Object)
   8:  {
   9:      Request = request
   8:  };

This declares that the request passed to the controller will actually be specified to contain content and a method (POST in this case).  Now that we have that, our tests won't fail with the awful (and unhelpful) "Object reference not set to an instance of an object" error you might be seeing.

In this case we've specified that the content will be a string, but we haven't specified any actual content.  But as I said before I needed to test whether the content was a file that had been uploaded, then also take certain actions based on that file.  To do that I actually needed to fake a file upload in the request itself.

A little bit of setup (this happens before each test run not each test):
   1:  [TestFixtureSetUp]
   2:  public void SetUpFixture()
   3:  {
   4:      using (var outFile = new StreamWriter(_testFile))
   5:      {
   6:          outFile.WriteLine("some test data");
   7:      }
   8:  }

The test:
   1:  [Test]
   2:  public void DoSomethingShouldReturnAnOkResult()
   3:  {
   4:      // arrange
   5:      var multipartContent = BuildFormDataContent();
   6:      multipartContent.Add(new StringContent("some value"), "someKey");
   7:   
   8:      var controller = new ExampleController(_moqLogger.Object)
   9:      {
  10:          Request = new HttpRequestMessage
  11:          {
  12:              Content = multipartContent,
  13:              Method = HttpMethod.Post
  14:          }
  15:      };
  16:   
  17:      // act
  18:      var response = controller.DoSomething();
  19:   
  20:      // assert
  21:      Assert.IsInstanceOf<OkResult>(response.Result);
  22:  }

The method called by the test:
   1:  private string _testFile = "test.file";
   2:   
   3:  private MultipartFormDataContent BuildFormDataContent()
   4:  {
   5:      var multipartContent = new MultipartFormDataContent("boundary=---011000010111000001101001");
   6:              
   7:      var fileStream = new FileStream(_testFile, FileMode.Open, FileAccess.Read);
   8:      var streamContent = new StreamContent(fileStream);
   9:      streamContent.Headers.ContentType = new MediaTypeHeaderValue("multipart/form-data");
  10:   
  11:      multipartContent.Add(streamContent, "TheFormDataKeyForTheFile", _testFile);
  12:   
  13:      return multipartContent;
  14:  }

And finally, the controller action method:
   1:  [HttpPost]
   2:  public async Task<IHttpActionResult> DoSomething()
   3:  {
   4:      if (!Request.Content.IsMimeMultipartContent("form-data"))
   5:      {
   6:          _logger.Information(() => "Unsupported media type");
   7:          return BadRequest("Unsupported media type");
   8:      }
   9:   
  10:      try
  11:      {
  12:          var root = @"C:\";
  13:          var provider = new MultipartFormDataStreamProvider(root);
  14:          await Request.Content.ReadAsMultipartAsync(provider);
  15:   
  16:          var someValue = provider.FormData.GetValues("someKey").FirstOrDefault();
  17:   
  18:          foreach (var file in provider.FileData)
  19:          {
  20:              var fileInfo = new FileInfo(file.LocalFileName);
  21:              // do something with the file here that returns a boolean
  22:              if(someOtherMethod()){
  23:                  return Ok();
  24:              }            
  25:   
  26:              return InternalServerError(new Exception("An error was encountered while processing the request"));
  27:          }
  28:   
  29:          return Ok();
  30:      }
  31:      catch (Exception ex)
  32:      {
  33:          return InternalServerError(ex);
  34:      }
  35:  }

This solved my problem and enabled me to test my action method on my controller.

Friday, November 18, 2016

More Fun with Shims

I'm finally back to doing some server side code (as opposed to the client stuff I've been working exclusively with for several months) and I found myself in need of some unit tests.  It's been a long time since I used a shim from Microsoft's Fakes framework so I had to poke and prod it for a while to work and I don't want to forget what I did.  Here goes:

In this particular example I was working with the WSUS API provided by Microsoft to interact with WSUS.  I specifically was trying to save a new signing certificate, but I obviously didn't want to actually do that on a WSUS server.  The solution was to use shims and stubs this time.

   1:  private string _fileNameParameter = "empty";
   2:  private SecureString _passwordParameter = new SecureString();

   1:  private StubIUpdateServer PrepareIUpdateServerStub()
   2:  {
   3:      FakesDelegates.Action<string, SecureString> setSigningCertificateAction = (fileName, password) =>
   4:      {
   5:          _fileNameParameter = fileName;
   6:          _passwordParameter = password;
   7:      };
   8:   
   9:      var iUpdateServerConfiguration = new StubIUpdateServerConfiguration
  10:      {
  11:          SetSigningCertificateStringSecureString = setSigningCertificateAction
  12:      };
  13:   
  14:      var iUpdateServerStub = new StubIUpdateServer
  15:      {
  16:          GetConfiguration = () => iUpdateServerConfiguration
  17:      };
  18:   
  19:      return iUpdateServerStub;
  20:  }

   1:  [TestMethod]
   2:  public void SetSigningCertificateShouldPassParametersToWsusApiAndReturnTrue()
   3:  {
   4:      using (ShimsContext.Create())
   5:      {
   6:          // arrange
   7:          const string expectedFileName = "fileName";
   8:          const string expectedPasswordString = "password";
   9:          var expectedPassword = new SecureString();
  10:          foreach (var c in expectedPasswordString)
  11:          {
  12:              expectedPassword.AppendChar(c);
  13:          }
  14:   
  15:          ShimAdminProxy.GetUpdateServerStringBooleanInt32 = (name, isSsl, port) => PrepareIUpdateServerStub();
  16:   
  17:          var wsusRepository = new WsusRepository();
  18:   
  19:          // act
  20:          var result = wsusRepository.SetSigningCertificate(expectedFileName, expectedPassword);
  21:   
  22:          // assert
  23:          Assert.AreEqual(expectedFileName, _fileNameParameter);
  24:          Assert.AreEqual(expectedPassword.ToString(), _passwordParameter.ToString());
  25:          Assert.IsTrue(result);
  26:      }
  27:  }

I broke out a bunch of the stub creation stuff so I could reuse it across multiple tests.  That's what the PrepareIUpdateServerStub method is for.  That's also why I have the global variables _fileNameParameter and _passwordParameter.  The method I was testing is essentially a pass-through to the WSUS API that we reuse in multiple applications so the method itself was fairly straightforward (check if a file and password were passed, then pass them on to WSUS).

Like I said at the beginning, working with Shims, Fakes, and Stubs is always a challenge for me so hopefully this documentation will help me next time I need to do it.

Friday, February 5, 2016

NUnit TestCase Attribute

The other day I showed how to use NUnit's TestCaseSource attribute to use a single test to run multiple cases.  Unfortunately, in my haste to get that post up I used a really bad example for it.  Let me refresh your memory.  Imagine we have a method that accepts three strings and returns one:

   1:  public string GetFullName(string firstName, string lastName, string middleName)
   2:  {
   3:      throw new NotImplementedException();
   4:  }

There's a really easy way to pass multiple cases to this method without using TestCaseSource.  You can just use the TestCase attribute.  If our test looks like this:

   1:  [Test]
   2:  public void GetFullName_ShouldConcatenateFirstMiddleAndLastWhenAllThreeHaveValues()
   3:  {
   4:      // arrange
   5:      var program = new Program();
   6:   
   7:      // act
   8:      var fullName = program.GetFullName("Jumping", "Flash", "Jack");
   9:   
  10:      // assert
  11:      Assert.AreEqual("Jumping Jack Flash", fullName);
  12:  }

We can change it to look like this, and it will run two separate tests:

   1:  [Test]
   2:  [TestCase("Jumping", "Flash", "Jack", "Jumping Jack Flash", "ShouldConcatenateFirstMiddleAndLastWhenAllThreeHaveValues")]
   3:  [TestCase("", "Flash", "Jack", "Jack Flash", "ShouldConcatenateMiddleAndLastWhenFirstIsEmptyString")]
   4:  public void GetFullName_ShouldMapNameCorrectly(string firstName, string lastName, string middleName, string expectation, string errorMessage)
   5:  {
   6:      // arrange
   7:      var program = new Program();
   8:   
   9:      // act
  10:      var fullName = program.GetFullName(firstName, lastName, middleName);
  11:   
  12:      // assert
  13:      Assert.AreEqual(expectation, fullName, errorMessage);
  14:  }

This is effectively the same thing as we saw the other day, but when you have simple types as all of your parameters, this is easier.  TestCaseSource really comes into play when you want to pass in a complex object as a parameter.  I'll try to post an example of that soon.

Friday, January 29, 2016

NUnit TestCaseSource Attribute

As you've probably picked up if you've read my other posts (I'm pretty sure I said it outright), I'm a huge fan of automated unit testing.  I've used MS Test and NUnit to test my C# code and I used to think they were pretty much equal.  However, I found something in NUnit recently that has me leaning their way.  To be fair, I'm not sure whether this is possible with MS Test and I have no reason to find out (we're using NUnit at the client).

I tend to write long test names.  Like, really long.  I tell people that I prefer clarity in the name over brevity.  I've also recently been converted to the single test philosophy where a single unit test only checks one thing.  That means that if you have a complex object of a Person you'd have one test for FirstName and another test for LastName, for example.  As you can probably imagine, my unit test files were pretty big.  That has a lot of negative ramifications, not the least of which is that it's hard to find whether you've already tested something.

UPDATE: This isn't the best example.  Check out this other post for a simpler way to do this.

Enter NUnit's TestCaseSourceAttribute and iterators.  What you can do is write a single test that accepts parameters, then create an iterator-based property that runs that test with different parameters.

Let's say we have a method called GetFullName, which takes a first, middle, and last name and concatenates them to make a full name:
   1:  public string GetFullName(string firstName, string lastName, string middleName)
   2:  {
   3:      throw new NotImplementedException();
   4:  }

So we write a basic test to confirm that when we pass all three parameters we get them back as "[first] [middle] [last]".  We'll call it "GetFullName_ShouldConcatenateFirstMiddleAndLastWhenAllThreeHaveValues":
   1:  [Test]
   2:  public void GetFullName_ShouldConcatenateFirstMiddleAndLastWhenAllThreeHaveValues()
   3:  {
   4:      // arrange
   5:      var program = new Program();
   6:   
   7:      // act
   8:      var fullName = program.GetFullName("Jumping", "Flash", "Jack");
   9:   
  10:      // assert
  11:      Assert.AreEqual("Jumping Jack Flash", fullName);
  12:  }

We update the method so the test passes:
   1:  public string GetFullName(string firstName, string lastName, string middleName)
   2:  {
   3:      return string.Format("{0} {1} {2}", firstName, middleName, lastName);
   4:  }

So now we have a problem.  Our test passes, but it's only the positive test case.  This method will clearly only work the way we want if we pass all three names.  If first name is null or empty we'll end up with a leading space we don't want.  We can create more tests to handle null values and empty strings, but that's a lot of combinations of values for a really simple method.  What we can do instead is use TestCaseSource and iterators.  Here's how we'd rewrite that one test this new way:
   1:  public static IEnumerable GetFullNameTestsCases
   2:  {
   3:      get
   4:      {
   5:          yield return
   6:              new TestCaseData("Jumping", "Flash", "Jack", "Jumping Jack Flash").SetName(
   7:                  "ShouldConcatenateFirstMiddleAndLastWhenAllThreeHaveValues");
   8:      }
   9:  }
  10:   
  11:  [Test, TestCaseSource("GetFullNameTestsCases")]
  12:  public void GetFullName(string firstName, string lastName, string middleName, string expectation)
  13:  {
  14:      // arrange
  15:      var program = new Program();
  16:   
  17:      // act
  18:      var fullName = program.GetFullName(firstName, lastName, middleName);
  19:   
  20:      // assert
  21:      Assert.AreEqual(expectation, fullName);
  22:  }

What we're doing here is creating the test data in the GetFullNameTestCases property, then we're specifying where the test should get its inputs by using the TestCaseSource attribute on the test itself.  As long as the number of parameters matches the number of arguments, everything will work fine.  Furthermore, we can add additional tests really easily just by adding more yield return statements.  Let's say we wanted to test for a null first name.  We just add this to the property:
   1:  yield return
   2:      new TestCaseData(null, "Flash", "Jack", "Jack Flash").SetName(
   3:          "ShouldConcatenateFirstMiddleAndLastWhenAllThreeHaveValues");

Next time we run our test, both sets of test data will get picked up and passed separately to the test method.  This method can greatly speed up your test writing and make it easier to cover more cases.

Mocking the Database

I believe I mentioned before that I worked with a custom, home-grown ORM at one of my clients.  If I didn't mention that, I'm mentioning it now.  One of the biggest problems I had with the solution we implemented was that we didn't have any tests for it.  Every now and then we'd encounter a new scenario (like returning a list of objects instead of a single object) and we'd have to code it in, with no way to make sure we weren't breaking what was already there.

One (particularly slow) day I decided enough was enough and I set out to create automated unit tests for every method in that behemoth.  That's when I encountered the problem: how do you mock a database for consumption by ADO.NET?  It turns out it's pretty easy and pretty straightforward.  First off, I found this code somewhere else (which, I know, technically violates the name of the blog, but it is what it is).  You can check out the original post here if you're interested.  I had to make a few changes for my version of MOQ and my specific circumstances, but that's the blog that got me started down the right path.

Here's the high level overview of the ORM: go get data using a DbDataReader, read through the columns in the reader, and for each column, find a corresponding property on the object and map the value from the reader to the property.  It's honestly pretty straightforward.  All I had to figure out was how to mock a DbDataReader.  Here it is:


   1:  private Mock<DbDataReader> CreateFakeDbDataReader(int numberOfFields, int numberOfReads = 1,
   2:              MockBehavior mockBehavior = MockBehavior.Loose, bool hasRows = true)
   3:  {
   4:      // create a mock repository (database)
   5:      var repository = new MockRepository(mockBehavior);
   6:      // create a reader for the mocked repository
   7:      var moqReader = repository.Create<DbDataReader>();
   8:      // setup the reader so that it always has rows (or indicates that it has rows anyway)
   9:      moqReader.SetupGet(p => p.HasRows).Returns(hasRows);
  10:      // setup the reader to indicate it has the specified number of fields
  11:      moqReader.SetupGet(p => p.FieldCount).Returns(numberOfFields);
  12:   
  13:      // readCounter is used to allow the reader to be iterated
  14:      // incrementing readCounter in the callback allows the reader to be read a specific number of times
  15:      var readCounter = 0;
  16:      moqReader.Setup(x => x.Read()).Returns(() => readCounter < numberOfReads).Callback(() => readCounter++);
  17:   
  18:      return moqReader;
  19:  }

When I want to mock a result set that has only one row I use this:
   1:  private DbDataReader CreateDataReaderWithSingleResultSet(Dictionary<string, object> values,
   2:              int numberOfReads = 1, bool hasRows = true)
   3:  {
   4:      // get the basic fake database reader
   5:      var moqReader = CreateFakeDbDataReader(values == null ? 0 : values.Count, numberOfReads, hasRows: hasRows);
   6:   
   7:      if (values == null)
   8:      {
   9:          return moqReader.Object;
  10:      }
  11:   
  12:      // iterate the objects (fake data)
  13:      for (var i = 0; i < values.Count; i++)
  14:      {
  15:          var item = values.ElementAt(i);
  16:          // setup the reader to return the name of the "field" when the index is used on GetName
  17:          moqReader.Setup(p => p.GetName(i)).Returns(item.Key);
  18:          // setup the reader to return the value when it encounters the key
  19:          // this is where we specify that if reader["FirstName"] is evaluated, "Fake" (or whatever) will be returned
  20:          moqReader.SetupGet(p => p[item.Key]).Returns(item.Value);
  21:          moqReader.SetupGet(p => p[i]).Returns(item.Value);
  22:      }
  23:   
  24:      return moqReader.Object;
  25:  }

And when I want to mock a result set that has multiple rows I use this:

   1:  private DbDataReader CreateDataReaderWithSingleResultSetWithMultipleRows(List<Dictionary<string, object>> rows,
   2:              bool hasRows = true)
   3:  {
   4:      // get the basic fake database reader
   5:      var moqReader = CreateFakeDbDataReader(rows.First().Count, rows.Count, hasRows: hasRows);
   6:   
   7:      var currentRow = 0;
   8:   
   9:      // iterate through the "rows" of data
  10:      for (var i = 0; i < rows.Count; i++)
  11:      {
  12:          // for each "row" in the data, check if the current row is being retrieved
  13:          if (i != currentRow)
  14:          {
  15:              continue;
  16:          }
  17:   
  18:          var row = rows[i];
  19:          // iterate through the "fields" in the current row
  20:          for (var j = 0; j < row.Count; j++)
  21:          {
  22:              var item = row.ElementAt(j);
  23:              // setup the reader to return the name of the "field" when the index is used on GetName
  24:              moqReader.Setup(p => p.GetName(j)).Returns(item.Key);
  25:              // setup the reader to return the value when it encounters the key
  26:              // this is where we specify that if reader["FirstName"] is evaluated, "Fake" (or whatever) will be returned
  27:              moqReader.SetupGet(p => p[item.Key]).Returns(item.Value);
  28:          }
  29:      }
  30:   
  31:      return moqReader.Object;
  32:  }

The one part that I never got coded because I didn't really need to was returning multiple result sets.  I'm sure it can be done, but I haven't had to do it yet.  Happy coding!