Are you tired of feeling like your code is meaningless? Sick of people not referring to your code as “black magic,” or struggling to gain recognition from your boss for writing sufficiently obfuscated code?
If you’ve answered “yes” to any of the above, Reflection might be for you!
Reflection
I’ve talked about reflection a couple of times before. It allows you to dive deep into a type and get out information at run time. This can be really handy, especially if you’re trying to make things easier for future programmers to add more functionality in the future without having to reinvent the entire process.
Recently I had created a series of classes that each contained a class with constant strings. These constant strings were an attempt to consolidate magic strings, which I hate. So, you can statically use the constant strings without instantiating the class. Basically, something like this:
Testing
I’ll leave the implementation details up to you, but suppose the Protocol needs to be able to handle each of the strings defined in the Incoming class and we want to write some tests to make sure that this is true.
You could easily enough write a generic test that has a series of inputs to test ([InlineData] if you’re using XUnit):
But what happens when you inevitably add another const string? You’ll have to remember to go update that test. I dunno about you, but I would almost certainly forget.
Testing with Reflection
Luckily, we can use reflection to create the test cases for us. We can easily lift the reflection that we wrote earlier to enumerate the constant strings in a class and add one extra step:
GetNestedType will let you get the class by name that is defined inside of the parent type.
GetNestedTypes will enumerate the classes that are defined inside of the parent type (in case you’re not sure which one you want).
I adapted this from an even more generic version where there were multiple classes that implemented an interface, and that interface was then used as a generics parameter to the test class. Since each class that implemented the interface also had (by convention) a class Incoming, I was able to use this technique to automate the testing.