Skip to content

[Bug]: TUnit0001 has allowance for implicit conversions, but these fail at runtime #5316

@ascott18

Description

@ascott18

Description

When a test class property is typed differently from the ClassDataSource generic argument, and the source type defines an implicit conversion operator to the property type, TUnit0001 correctly allows the code to compile. However, at runtime the generated SetProperty code does a direct cast from object — (TargetType)value — which bypasses user-defined implicit/explicit operators, resulting in an InvalidCastException.

The generated code (from PropertyInjectionSourceGenerator) emits:

GetDbBackingField(typedInstance) = (global::MyDbContext)value;

Since value is object, this is a reference cast, not a C# conversion. It should emit:

GetDbBackingField(typedInstance) = (global::MyDbContext)(global::MyDbFixture)value;

— first unbox to the source type, then let the user-defined operator invoke.

Expected Behavior

Property injection succeeds. The implicit operator converts MyDbFixture to MyDbContext and the test runs.

Actual Behavior

InvalidCastException: Unable to cast object of type 'MyDbFixture' to type 'MyDbContext'.

Steps to Reproduce

public class MyDbContext(string connStr)
{
    public string ConnStr { get; } = connStr;
}

public class MyDbFixture : IAsyncDisposable
{
    public static implicit operator MyDbContext(MyDbFixture f) => new("test-conn");
    public ValueTask DisposeAsync() => ValueTask.CompletedTask;
}

public class ImplicitOperatorTests
{
    [ClassDataSource<MyDbFixture>]
    public required MyDbContext Db { get; init; }

    [Test]
    public async Task Injection_Works() => await Assert.That(Db).IsNotNull();
}

TUnit Version

1.23.7

.NET Version

.NET 10

Operating System

Windows

IDE / Test Runner

dotnet CLI (dotnet test / dotnet run)

Error Output / Stack Trace

System.InvalidCastException: Unable to cast object of type 'MyProject.Data.Test.MyDbFixture' to type 'MyProject.Data.Test.MyDbContext'.
   at TUnit.Core.PropertyInjectionSource_36d26bd4.<>c.<GetPropertyMetadata>b__5_1(Object instance, Object value) in D:\MyProject\MyProject.Data.Test\obj\Debug\net10.0\TUnit.Core.SourceGenerator\TUnit.Core.SourceGenerator.Generators.PropertyInjectionSourceGenerator\MyProject_Data_Test_ImplicitOperatorTests_PropertyInjection.g.cs:line 45
   at TUnit.Engine.Services.ObjectLifecycleService.SetCachedPropertiesOnInstance(Object instance, TestContext testContext)
   at TUnit.Engine.Services.ObjectLifecycleService.PrepareTest(TestContext testContext)
   at TUnit.Engine.TestInitializer.PrepareTest(AbstractExecutableTest test, CancellationToken cancellationToken)
   at TUnit.Engine.Services.TestExecution.TestCoordinator.ExecuteTestLifecycleAsync(AbstractExecutableTest test, CancellationToken cancellationToken)

Additional Context

No response

IDE-Specific Issue?

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

Metadata

Metadata

Labels

bugSomething isn't working

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions