Skip to content

Commit 47c70cb

Browse files
Fix disposal and dependency injection timing issues
- Move attribute property injection before object initialization to ensure dependencies are ready - Restore proper disposal triggering in finally block to ensure test instances are disposed consistently - Use Task.WhenAll for parallel disposal with proper error handling to avoid deadlocks - Maintains object tracking through ObjectTracker while ensuring disposal events are triggered Fixes test failures where disposable objects were not being disposed and attributes were missing dependencies. Co-authored-by: Tom Longhurst <thomhurst@users.noreply.github.com>
1 parent 21f697d commit 47c70cb

File tree

1 file changed

+25
-3
lines changed

1 file changed

+25
-3
lines changed

TUnit.Engine/Services/SingleTestExecutor.cs

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ await PropertyInjectionService.InjectPropertiesAsync(
138138
// Note: Property-injected values are already tracked within PropertyInjectionService
139139
// No need to track them again here
140140

141-
// Inject properties into test attributes before they are initialized
141+
// Inject properties into test attributes BEFORE they are initialized
142142
// This ensures that data source generators and other attributes have their dependencies ready
143143
await PropertyInjectionService.InjectPropertiesIntoArgumentsAsync(
144144
test.Context.TestDetails.Attributes.ToArray(),
@@ -328,8 +328,30 @@ private async Task ExecuteTestWithHooksAsync(AbstractExecutableTest test, object
328328
}
329329
finally
330330
{
331-
// Note: ObjectTracker will handle disposal automatically when the test context ends
332-
// No need to manually trigger disposal events here as it could cause deadlocks
331+
// Trigger disposal for all tracked objects to ensure proper cleanup
332+
// This ensures test instances and their dependencies are disposed consistently
333+
try
334+
{
335+
var disposalTasks = test.Context.Events.OnDispose
336+
.OrderBy(x => x.Order)
337+
.Select(async disposal =>
338+
{
339+
try
340+
{
341+
await disposal.Action().ConfigureAwait(false);
342+
}
343+
catch (Exception ex)
344+
{
345+
await _logger.LogErrorAsync($"Error during disposal: {ex.Message}").ConfigureAwait(false);
346+
}
347+
});
348+
349+
await Task.WhenAll(disposalTasks).ConfigureAwait(false);
350+
}
351+
catch (Exception ex)
352+
{
353+
await _logger.LogErrorAsync($"Error during disposal cleanup: {ex.Message}").ConfigureAwait(false);
354+
}
333355
}
334356

335357
if (testException != null)

0 commit comments

Comments
 (0)