Skip to content

[Bug]: MethodDataSource source generator uses the wrong class #6365

Description

@Lexy2

Description

Typed version of MethodDataSourceAttribute generates the wrong InstanceMethodDataSource using the parent class instance instead of a child one.

Expected Behavior

Class passed into the attribute is instantiated for data source.

Actual Behavior

Parent class was used and test fails at runtime.

Steps to Reproduce

It's a bit hard for me to provide a good repro but hopefully this pseudocode would do:

public class A
{
    [Test]
    [MethodDataSource<B>("GetTestCases")]
    public void TestMethod(TestCase tc) { }

    public record TestCase(int a, double b);

    public class B : C
    {
        protected override IEnumerable<TestCase> GenerateTestCases()
        {
            yield return new TestCase(1, 2);
        }
    }

    public abstract class C
    {
        public IEnumerable<TestCase> GetTestCases()
        {
             foreach (var testCase in GenerateTestCases())
             {
                 yield return testCase;
             }
        }

        protected abstract IEnumerable<TestCase> GenerateTestCases();
    }
}

TUnit Version

1.58.0

.NET Version

.NET 10

Operating System

Windows

IDE / Test Runner

dotnet CLI (dotnet test / dotnet run)

Error Output / Stack Trace

[Test Failure] Unable to cast object of type 'A' to type 'B'.

<.cctor>b__17_23(Object instance) line 341
DataSourceFactories.FromInstanceEnumerable(DataGeneratorMetadata dataGeneratorMetadata, Func`2 invoke)+MoveNext()
Boolean>.GetResult()
MethodDataSourceAttribute.GetDataRowsAsync(DataGeneratorMetadata dataGeneratorMetadata)+MoveNext()
MethodDataSourceAttribute.GetDataRowsAsync(DataGeneratorMetadata dataGeneratorMetadata)+MoveNext()
Boolean>.GetResult()
TestBuilder.GetInitializedDataRowsAsync(IDataSourceAttribute dataSource, DataGeneratorMetadata dataGeneratorMetadata, CancellationToken cancellationToken)+MoveNext()
TestBuilder.GetInitializedDataRowsAsync(IDataSourceAttribute dataSource, DataGeneratorMetadata dataGeneratorMetadata, CancellationToken cancellationToken)+MoveNext()
Boolean>.GetResult()
TestBuilder.BuildTestsFromMetadataAsync(TestMetadata metadata, TestBuildingContext buildingContext, CancellationToken cancellationToken)
TestBuilder.BuildTestsFromMetadataAsync(TestMetadata metadata, TestBuildingContext buildingContext, CancellationToken cancellationToken)
TestBuilder.BuildTestsFromMetadataAsync(TestMetadata metadata, TestBuildingContext buildingContext, CancellationToken cancellationToken)

Additional Context

This looks like a regression introduced in 1.51.0. If I downgrade TUnit to 1.50.0, tests pass.

The generated code for the test is different and passes the right class to CastHelper.Cast.

IDE-Specific Issue?

  • I've confirmed this issue occurs when running via dotnet test or dotnet run, not just in my IDE

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions