Last week, we saw how the Fixie test framework deals with test method parameters. Your custom convention calls a Parameters(…) hook, supplying an explanation of where parameters should come from and how many times the test method should be called. The example convention was a little underwhelming, since parameters had to be explicitly listed within [Input] attributes. Today, we’ll get our parameter values from somewhere more interesting, AutoFixture.
Parameterized tests are useful when a single test method needs to run many times against a large set of independent inputs. However, it’s perfectly reasonable for parameterized tests to be called a single time, and in this case the purpose of using parameters is to hide away some otherwise-distracting instantiation code. Your test can focus on the actual system-under-test. AutoFixture’s a great example for single-call parameterized test methods, since it’s purpose is to automate boring class-population code you’d rather not clutter your tests with.
Let’s start with a simple Person class:
Next, I have a test class with three tests. Two of the tests have parameters. Since I’m just investigating Fixie’s ability to pass meaningful values to these tests, they write the actual incoming values to the console instead of making assertions:
I haven’t told Fixie what it means for a test to have parameters, so when we run our test under the default convention we see some failures:
Today, I’d like parameters to come from AutoFixture, similar to AutoFixture’s support for xUnit Theories. I needed to define an extension method for AutoFixture first, though, because normal AutoFixture usage involves knowing ahead of time what type to instantiate. Instead, we want to be able to ask AutoFixture to instantiate any arbitrary Type:
Finally, I define a custom convention which takes advantage of the Parameters(…) hook introduced last week:
As we saw last week, the inherited Parameters(…) method wants you to provide a method that takes in a MethodInfo and returns an IEnumerable<object>, since in general it needs to support any number of calls to a given test method. For today’s AutoFixture convention, though, we really just want to call each parameterized test once, and we want parameters to be based simply on the parameter types. Therefore, this convention includes a convenience overload for Parameters(…) which accepts a Func<Type, object>. This overload finds a single value for each parameter, based on its type, and returns a single-item array to provoke a single call to each test method. If it proves useful in general, I’ll promote this overload to be accessible from any convention.
Running the tests again, we see that each test is successfully passed values generated by AutoFixture: