Alex K
Alex K

Reputation: 135

xUnit test class internal

I need xUnit to work with internal test classes. The problem is that I have used a generic base test fixture UnitTestBase. So I create my fixture as

class MyFixture: UnitTestBase<SomeSystemUnderTheTest>
{
...
}

In some cases SomeSystemUnderTheTest appears to be internal class. Lets call it SomeSystemUnderTheTestInternal. As result UnitTestBase<SomeSystemUnderTheTestInternal> also appear to be internal even if UnitTestBase public. As result of that I can't specify MyFixture to be public as compiler says your base class has less accessibility. So MyFixture in my case only can be internal, but then xUnit requires it to be public. Is there a workaround to make xUnit work with internal fixtures?

SomeSystemUnderTheTest is a class which implements some interface. It is not used directly anywhere it is just got injected by DI container. It was marked as internal. I have slightly simplified our situation above, SomeSystemUnderTheTest is in fact derived from a generic class SomeSystemUnderTheTestBase, where SomeInternalClass is an internal class and as result of this the whole tree is internal. I can't change it as it is not something we wanna do.

Upvotes: 3

Views: 1398

Answers (2)

brandonstrong
brandonstrong

Reputation: 688

Late answer, but just had to figure this out for myself. Here is one potential workaround pattern, coded in .NET 8:

Create a TestBase class

Define any test methods here

public abstract class TestBase
{
    [Fact]
    public abstract void TestMethod();
}

Modify UnitTestBase

Inherit from TestBase so this can be used as a delegate

public abstract class UnitTestBase<TSubjectUnderTest> : TestBase
{
    [Fact]
    public override void TestMethod()
    {
        // Implement test for TSubjectUnderTest
    }
}

Create a DelegateTestBase base class

Implement the test methods and delegate them. This is where the work-around actually happens

public abstract class DelegateTestBase : TestBase
{
    protected abstract TestBase GetDelegate();

    [Fact]
    public override void TestMethod
        => GetDelegate().TestMethod();
}

Modify MyFixture

Implement delegate pattern here

public class MyFixture : DelegateTestBase
{
    private class Delegate : UnitTestBase<SomeSystemUnderTheTest>;

    protected override TestBase GetDelegate() => new Delegate();
}

This works because MyFixture is public and can be discovered by xUnit. It allows the generic type class for the internal SomeSystemUnderTheTest to be provided by the delegate.

Upvotes: 0

Shafiq Jetha
Shafiq Jetha

Reputation: 1556

Add this just above the namespace declaration in your SomeSystemUnderTestInternal file:

[assembly: InternalsVisibleToAttribute("TestProject")]

Where TestProject is the assembly name of the project that contains your test class.

Upvotes: 3

Related Questions