Question

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.

The problem:

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 },
 [...]
Était-ce utile?

La solution

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:

  • make CheckByteRange into a static method
  • tell it which instance to use, i.e. (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 },
          };
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top