Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test method with 'out' parameter(s)?

I am trying to write a unit test for a method that has out parameters. My method specifically is a TryParse method for my custom object. I am using .NET 4.5/5 with Visual Studio 2013. This allows me to fully realize private/internal and static objects using the PrivateType object. The one thing that seems to escape me is how to test for the out parameter as I cannot use this keyword in the InvokeStatic method. I am looking for the proper solution to test this architecture design.

The use for TryParse is part of a TypeConverter process as outlined in the WebAPI Parameter Binding post By Mike Wilson

public class MyFilter
{
    public string Field { get; set; }
    //... removed for brevity

    internal static bool TryParse(string sourceValue, out MyFilter filter)
    {
        //... removed for brevity
    }
}

public class MyFilterTests
{
    [TestMethod]
    [TestCategory("TryParse")]
    public void TryParseWithTitleOnly()
    {
        var stringSource = "{field:'DATE.FIELD'}";

        MyFilter tryParseOut = null;

        var target = new PrivateType(typeof(MyFilter));

        var tryParseReturn = target.InvokeStatic("TryParse", stringSource, tryParseOut);

        var expectedOut = new MyFilter()
        {
            Field = "DATE.FIELD"
        };

        Assert.IsTrue((bool)tryParseReturn);
        Assert.AreEqual(expectedOut, tryParseOut);
    }
}
like image 249
Itanex Avatar asked Mar 10 '15 17:03

Itanex


People also ask

How do you use out parameters?

For using out keyword as a parameter both the method definition and calling method must use the out keyword explicitly. The out parameters are not allowed to use in asynchronous methods. The out parameters are not allowed to use in iterator methods. There can be more than one out parameter in a method.


Video Answer


1 Answers

Personally, I'd use InternalsVisibleTo in order to make the method visible to your test code, but if you do want to use PrivateType, I'd expect you to be able to just create an object[] which you keep a reference to, pass it into InvokeStatic, and then get the value out again:

object[] args = new object[] { stringSource, null };
var tryParseReturn = target.InvokeStatic("TryParse", args);

...

// args[1] will have the value assigned to the out parameter
Assert.AreEqual(expectedOut, args[1]);

At least, I'd expect that to work - that's how reflection generally handles ref and out parameters.

like image 65
Jon Skeet Avatar answered Oct 08 '22 19:10

Jon Skeet