Skip to content

Abstract Class [Before(Test)] breakage #2887

Description

@viceroypenguin

The following code builds and displays ActualTestClas.Test1 as a test with TUnit 0.25.21:

using System.Diagnostics.CodeAnalysis;
using TUnit.Core.Interfaces;

public interface IServiceProvider;

public sealed class DependencyInjectionClassConstructor : IClassConstructor
{
    public object Create([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type type, ClassConstructorMetadata classConstructorMetadata)
    {
        throw new NotImplementedException();
    }
}

public abstract class BaseTestClass(IServiceProvider serviceProvider)
{
    [Before(Test)]
    public Task Hook() => Task.CompletedTask;

}

[ClassConstructor<DependencyInjectionClassConstructor>]
public sealed class ActualTestClass(IServiceProvider serviceProvider)
    : BaseTestClass(serviceProvider)
{
    [Test]
    public void Test1() { }
}

However, updating to 0.55.6 (and modifying Create() to fit the updated interface), I get the following error during test discovery:

[ConsoleApp1.dll] Unhandled exception. System.TypeInitializationException: The type initializer for 'TUnit.Generated.Hooks.GeneratedHookRegistry' threw an exception.
 ---> System.InvalidOperationException: Failed to initialize hook registry: Object reference not set to an instance of an object.
 ---> System.NullReferenceException: Object reference not set to an instance of an object.
   at TUnit.Generated.Hooks.GeneratedHookRegistry.<>c.<PopulateSourcesDictionaries>b__1_1() in D:\viceroypenguin\ConsoleApp1\obj\Debug\net9.0\TUnit.Core.SourceGenerator\TUnit.Core.SourceGenerator.Generators.HookMetadataGenerator\GeneratedHookSource.g.cs:line 50
   at TUnit.Core.ClassMetadata.<>c__DisplayClass3_0.<GetOrAdd>b__0(String _)
   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
...

I think the issue is that the hook generator is looking for the constructor to BaseTestClass, however that constructor is (correctly) protected since it can only be constructed as an instance of a subclass. This works in earlier versions of TUnit.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions