Nodoid
Nodoid

Reputation: 1581

Passing a property as an Xunit Theory

I'm trying to create a simple Xunit test that will take a property (not a property.name rather the full property) as a datatype.

I've looked at the three types available so I can pass as the Inline/Member/Class Data and none of them really fit.

My properties are created like this

TokenStore nullTokenStore { get; set; } = new TokenStore();
TokenStore tokenStore { get; set; } = new TokenStore { RefreshToken = "12345", BearerToken = "fredfox" };

(so nothing out of the ordinary)

If I pass the property directly into InlineData (as is), I get an error that the property is not null and must be a const, typeof or array. If I make the property static and refer to the member names, I get a different error, but still not accepted.

My full test case looks like this

[Theory]
[InlineData(tokenStore.BearerToken, tokenStore.RefreshToken)]
public async Task Test_GetProductApiURL(TokenStore store)
{
    var service = await _fixture.GetProductApiURLAsync();

    Assert.NotNull(service);
    Assert.NotNull(service.ReasonPhrase);
    Assert.Equal((int)service.StatusCode, 200);
}

Is there a way to pass in a complete property?

Upvotes: 1

Views: 1392

Answers (1)

Isak Engström
Isak Engström

Reputation: 397

You can't pass in objects directly using the InlineData attribute. In order to pass in objects, I'd suggest opting for the MemberData attribute instead. Something like this:

    public static IEnumerable<object[]> TokenStoreTestData()
    {
        yield return new object[] { new TokenStore() };
        yield return new object[] { new TokenStore { RefreshToken = "12345", BearerToken = "fredfox" } };
    }
    
    [Theory]
    [MemberData(nameof(TokenStoreTestData))]
    public async Task Test1(TokenStore store)
    {
        // access store.BearerToken or store.RefreshToken in here and use in your test
    }

Read more in this other thread

A workaround you can use if InlineData is your only option, is to construct the object inside the test, something like this:

    [Theory]
    [InlineData(null, null)]
    [InlineData("12345", "fredfox")]
    public async Task Test2(string? refreshToken, string? bearerToken)
    {
        TokenStore store;
        if (refreshToken is null || bearerToken is null)
        {
            store = new TokenStore();
        }
        else
        {
            store = new TokenStore
            {
                RefreshToken = refreshToken,
                BearerToken = bearerToken
            };
        }
        // access store.BearerToken or store.RefreshToken here and use in your test
    }

Upvotes: 3

Related Questions