Skip to content

MethodDataSources with IAsyncEnumerable<T> throw invalid cast exception #2990

@AnnaSasDev

Description

@AnnaSasDev

Description

When using MethodDataSource with an IAsyncEnumerable, TUnit throws an InvalidCastException at runtime.

Reproduction

Following the official docs, I set up tests that return data from an IAsyncEnumerable.
Both with a custom record type and with tuples, like in the original example, the result is the same: the test runner seems to attempts to cast the compiler-generated async iterator (<GetAsyncTestData>d__0 / <GetSimpleAsyncData>d__1) directly to the test data type, instead of unwrapping the yielded values.

I have created a minimal repo that contains the error https://github.com/AnnaSasDev/TUnitAsyncEnumerableBug/

Actual behavior

Both tests fail with an InvalidCastException.

  • On a custom record type:
Unable to cast object of type '<GetAsyncTestData>d__0' to type 'TUnitAsyncEnumerableBug.AsyncTestData'.
   at TUnit.Core.Helpers.CastHelper.Cast[T](Object value)
   at TUnit.Generated.AsyncDataSourceTests_TestWithAsyncComplexData_TestSource_5951bb69bd7449e1b798409e9bf2573e.<>c.<<GetTestsAsync>b__0_3>d.MoveNext() in D:\Dev\sources\external\TUnitAsyncEnumerableBug\TUnitAsyncEnumerableBug\TUnitAsyncEnumerableBug\obj\Debug\net9.0\TUnit.Core.SourceGenerator\TUnit.Core.SourceGenerator.Generators.TestMetadataGenerator\AsyncDataSourceTests_TestWithAsyncComplexData_52947a1b26964db68fe3bb6412b2a549.g.cs:line 118
--- End of stack trace from previous location ---
   at TUnit.Core.TestMetadata`1.<>c__DisplayClass13_0.<<get_CreateExecutableTestFactory>b__2>d.MoveNext()
--- End of stack trace from previous location ---
   at TUnit.Core.ExecutableTest.InvokeTestAsync(Object instance, CancellationToken cancellationToken)
   at TUnit.Engine.Services.SingleTestExecutor.<>c__DisplayClass20_0.<<CreateTimeoutTestAction>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at TUnit.Engine.Services.SingleTestExecutor.InvokeWithTestExecutor(DiscoveredTest discoveredTest, TestContext context, Func`1 testAction)
   at TUnit.Engine.Services.SingleTestExecutor.InvokeTestWithTimeout(AbstractExecutableTest test, Object instance, CancellationToken cancellationToken)
   at TUnit.Engine.Services.SingleTestExecutor.ExecuteTestWithHooksAsync(AbstractExecutableTest test, Object instance, CancellationToken cancellationToken)
   at TUnit.Engine.Services.SingleTestExecutor.ExecuteTestWithHooksAsync(AbstractExecutableTest test, Object instance, CancellationToken cancellationToken)
   at TUnit.Engine.Services.SingleTestExecutor.ExecuteTestInternalAsync(AbstractExecutableTest test, CancellationToken cancellationToken)
  • On a tuple:
Unable to cast object of type '<GetSimpleAsyncData>d__1' to type 'System.ValueTuple`2[System.Int32,System.String]'.
   at TUnit.Core.Helpers.CastHelper.Cast[T](Object value)
   at TUnit.Generated.AsyncDataSourceTests_TestWithAsyncSimpleData_TestSource_dbfa548c6f794c4cb29cfa0041e0a27b.<>c.<<GetTestsAsync>b__0_3>d.MoveNext() in D:\Dev\sources\external\TUnitAsyncEnumerableBug\TUnitAsyncEnumerableBug\TUnitAsyncEnumerableBug\obj\Debug\net9.0\TUnit.Core.SourceGenerator\TUnit.Core.SourceGenerator.Generators.TestMetadataGenerator\AsyncDataSourceTests_TestWithAsyncSimpleData_3d4756c35f5a4d898dd7156619040ec3.g.cs:line 118
--- End of stack trace from previous location ---
   at TUnit.Core.TestMetadata`1.<>c__DisplayClass13_0.<<get_CreateExecutableTestFactory>b__2>d.MoveNext()
--- End of stack trace from previous location ---
   at TUnit.Core.ExecutableTest.InvokeTestAsync(Object instance, CancellationToken cancellationToken)
   at TUnit.Engine.Services.SingleTestExecutor.<>c__DisplayClass20_0.<<CreateTimeoutTestAction>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at TUnit.Engine.Services.SingleTestExecutor.InvokeWithTestExecutor(DiscoveredTest discoveredTest, TestContext context, Func`1 testAction)
   at TUnit.Engine.Services.SingleTestExecutor.InvokeTestWithTimeout(AbstractExecutableTest test, Object instance, CancellationToken cancellationToken)
   at TUnit.Engine.Services.SingleTestExecutor.ExecuteTestWithHooksAsync(AbstractExecutableTest test, Object instance, CancellationToken cancellationToken)
   at TUnit.Engine.Services.SingleTestExecutor.ExecuteTestWithHooksAsync(AbstractExecutableTest test, Object instance, CancellationToken cancellationToken)
   at TUnit.Engine.Services.SingleTestExecutor.ExecuteTestInternalAsync(AbstractExecutableTest test, CancellationToken cancellationToken)

Environment

  • TUnit version: 0.57.1
  • .NET version: net9.0
  • OS: Windows 11

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