Can I make internal enum visible to the test project, and use it in public test method?

134 views Asked by At

I have internal enum MyEnum in the project. And I also have a custom attribute on some of the values of MyEnum, like:

internal enum MyEnum
{
    [CustomAttribute("value")]
    EnumValue,
}

My project also contains class InternalsVisibleTo.cs: [assembly: InternalsVisibleTo("MyTestProjectName")]

And I'd like to cover this attribute in xUnit Theory, i.e.:

[Theory]
[InlineData(MyEnum.EnumValue, "value")]
public void MyAttributeWorksCorrectly(MyEnum myEnum, string expectedAttributeValue) 
{
}

Because InternalsVisibleTo - InlineData has access to the enum. However, I get the following error:

Inconsistent accessibility: parameter type 'MyTestProjectName.MyEnum' is less accessible than method 'MyAttributeWorksCorrectly'

Sure - this is violation.

Question - can I bypass it somehow without makine MyEnum public?

I've already read few articles:

https://learn.microsoft.com/en-us/dotnet/standard/assembly/friend https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/access-modifiers https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/accessibility-levels

2

There are 2 answers

0
toni On

That is because you method MyAttributeWorksCorrectly is public, that means that anybody could call this method. But MyEnum is internal which means only the current assembly (and any assembly that you define with InternalsVisibleTo-attribute) has access to this Type.

Think about that, what if your test assembly gets used by somebody else, and they want to call the Method MyAttributeWorksCorrectly, they would also know of the existence of MyEnum which they should not because of the internal-modifier. That is why the compiler does not let you compile.

You can fix this Issue by simply marking the UniTest as internal or by using a [Fact]-UnitTest, of course there you do not have the possibility with dynamic data.

[Theory]
[InlineData(
    MyEnum.EnumValue,
    "value"
)]
internal void Test1(MyEnum myEnum, string expectedValue)
{
    string? attributeValue = myEnum.GetType()
        .GetTypeInfo()
        .DeclaredMembers.First(
            x => x.Name == myEnum.ToString()
        )
        ?.GetCustomAttribute<CustomAttribute>(
            false
        )
        ?.Value;

    Assert.NotNull(
        attributeValue
    );

    Assert.Equal(
        expectedValue,
        attributeValue
    );
}

[Fact]
public void MyAttributeWorksCorrectly()
{
    const MyEnum myEnum = MyEnum.EnumValue;

    string? attributeValue = myEnum.GetType()
        .GetTypeInfo()
        .DeclaredMembers.First(
            x => x.Name == myEnum.ToString()
        )
        ?.GetCustomAttribute<CustomAttribute>(
            false
        )
        ?.Value;

    Assert.NotNull(
        attributeValue
    );

    Assert.Equal(
        "value",
        attributeValue
    );
}
1
mati On

Hmm... I found out the workaround :/ It is a little bit silly to answer my own question. Maybe the question should be reported for deletion?

Workaround:

[Theory]
[InlineData(nameof(MyEnum.EnumValue), "value")]
public void MyAttributeWorksCorrectly(string nameOfEnumField, string expectedAttributeValue) 
{
    Enum.Parse<MyEnum>(nameOfEnumField);
}

I am curious what others think... Please share your thoughts...