Learn AspNet
Learn AspNet

Reputation: 1622

Pass in array of certain size to test with xunit

I need help with writing unit test with xunit. I am trying to test a validation where array length cannot be greater than 20MB

[Theory]
[InlineData((arrayGreaterThan20MB())]
public void Fail_when_documentSize_is_greater(byte[] documentSize)
{
    _getAccountFileViewModel.Content = documentSize;
}

Private Function

private static byte[] arrayGreaterThan20MB()
{
    byte[] arr = new byte[5000000000];
    return arr;
}

I am not sure what is the best way to test this. I am getting a error when I am trying to pass function in inline data.

Error "An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type"

Upvotes: 4

Views: 3523

Answers (2)

Philipp Grathwohl
Philipp Grathwohl

Reputation: 2836

You can not use the result of a method call as parameter of an attribute. That's what the error is telling you. You can only pass constants or literals. For example like this:

[Theory]
[InlineData("a", "b")]
public void InlineDataTest(string first, string second)
{
    Assert.Equal("a", first);
    Assert.Equal("b", second);
}

XUnit has some other attributes, that can help you here. E.g. there is the MemberData attribute, that allows you to specify a method name of a method that provides the test data. Note that it returns an IEnumerable of object array. Each object array will be used to call the test method once. The content of the object array are the parameters. For example:

[Theory]
[MemberData(nameof(DataGeneratorMethod))]
public void MemberDataTest(string first, string second)
{
    Assert.Equal("a", first);
    Assert.Equal("b", second);
}

public static IEnumerable<object[]> DataGeneratorMethod()
{
    var result = new List<object[]>();   // each item of this list will cause a call to your test method
    result.Add(new object[] {"a", "b"}); // "a" and "b" are parameters for one test method call
    return result;

    // or 
    // yield return new object[] {"a", "b"};
}

In the case you mentioned above, the simplest way would be just to call your method that creates the test data within your test method.

[Theory]
public void Fail_when_documentSize_is_greater()
{
    _getAccountFileViewModel.Content = arrayGreaterThan20MB();
}

There is another attribute called ClassData that can use a data generator class. More detailed information can be found on this blog post

Upvotes: 1

Nkosi
Nkosi

Reputation: 247461

Just declare the array within the test itself, instead of trying to pass via inline data attribute

[Theory]
public void Fail_when_documentSize_is_greater() {
    byte[] overSizedDocument =  new byte[5000000000];
    _getAccountFileViewModel.Content = overSizedDocument;

    //...
}

Upvotes: 2

Related Questions