Search code examples
c#unit-testingreflectionxunit

GetAttributes() Not Returning All Attributes


I'm trying to write a test that checks I can deserialise all of my enums with the [JsonConverter(typeof(JsonEnumConverter))] attribute,

So I've got this (in-progress) test generator code:

private class TestDataGenerator: IEnumerable<object[]>
{

    public IEnumerator<object[]> GetEnumerator()
    {
        var allEnums = typeof(RecordType).Assembly.GetTypes().Where(t => t.IsEnum);
        var testEnums = allEnums.Where(e => e.GetCustomAttributes().Any(a => a is JsonConverter));
        var enumMemberInfo = testEnums.SelectMany(e => e.GetMembers(BindingFlags.Static | BindingFlags.Public));
        IEnumerable<object[]> enumsWithNames = enumMemberInfo.Select(e =>
                                                                     {
                                                                         Enum.TryParse(e.Name, out RecordType res);
                                                                         return new object[]
                                                                                {
                                                                                    res,
                                                                                    ((JsonPropertyNameAttribute)e.GetCustomAttributes().First(a => a is JsonPropertyNameAttribute)).Name
                                                                                };
                                                                     });
        return enumsWithNames.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}

If I scrap the testEnums.SelectMany and run it with typeof(RecordObject) directly, this works.

So jumping on the debugger, the issue seems to be that testEnums evaluates to nothing. If I then look at allEnums[0].GetCustomAttributes(), the [JsonConverter(T)] is nowhere to be seen.

Here's my enum:

[JsonConverter(typeof(JsonStringEnumConverter))] 
public enum RecordType
{
        [JsonPropertyName("country")]
        Country = 1,

        [JsonPropertyName("destinationOrbit")]
        DestinationOrbit = 2,

        // etc
}

Any ideas why this attribute apparently doesn't exist on my enum and how I can get this info at runtime?


Solution

  • You have to filter by JsonConverterAttribute instead of JsonConverter

    var testEnums = allEnums.Where(e => e.GetCustomAttributes().Any(a => 
                a is JsonConverterAttribute));
    

    Visual Studio will only display JsonConverter instead of JsonConverterAttribute above the class, but if you hover your cursor over the type then you will see the full name.

    The JsonConverter is a different type.