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?
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:
Since value is object, this is a reference cast, not a C# conversion. It should emit:
— 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
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
Additional Context
No response
IDE-Specific Issue?
dotnet testordotnet run, not just in my IDE