Disclaimer: the unit-test related info for this question is not really relevant - you can skip to "The Problem" if you're not familiar with this, but it helps set the context.
I have a class that I need to unit-test. It looks like this:
public class NumberParser {
public static void CheckByteRange(string str){...}
[...]
public static void CheckFloatRange(string str){...}
[...]
}
I want to use an NUnit parametrized unit-test to test all these methods. Here's the test method:
[TestCaseSource("CheckRange_Overflow_Inputs")]
public void CheckRange_Overflow(string value, Action<string> method)
{
Assert.Throws<Exception>(() => method(value));
}
The test uses TestCaseSourceAttribute
to specify a field that contains a list of sets of arguments to the test method.
Now, NUnit expects a field called CheckRange_Overflow_Inputs
, of type object[]
, that itself contains object[]
elements, each of which contains values for the arguments to the test method.
Ideally, I'd like to write the field like this:
private static readonly object[] CheckRange_Overflow_Inputs
= new object[]
{
new object[]{byte.MaxValue, NumberParser.CheckByteRange },
[...]
new object[]{float.MaxValue, NumberParser.CheckFloatRange },
[...]
};
But the compiler complains it can't cast a method group to an object.
That makes sense - NumberParser.CheckByteRange
could be ambiguous, e.g. it could be overloaded.
But how can I get the compiler to allow me to save (as an object) the method called NumberParser.CheckByteRange
that takes a string
and returns void
?
What I tried (and failed succeeded):
[...]
new object[]{byte.MaxValue, (Action<string>)NumberParser.CheckByteRange },
[...]
If the method was static
, then your attempt would have worked. It can't work simply as
(Action<string>)NumberParser.CheckByteRange
when CheckByteRange
is an instance (non-static
) method because you haven't told it which instance (this
) to use. So either:
CheckByteRange
into a static
method(Action<string>)someInstance.CheckByteRange
With them static
, the following compiles fine for me:
private static readonly object[] CheckRange_Overflow_Inputs
= new object[]
{
new object[]{byte.MaxValue, (Action<string>) NumberParser.CheckByteRange },
new object[]{float.MaxValue, (Action<string>) NumberParser.CheckFloatRange },
};