1+ using TUnit . Core ;
2+ using TUnit . Core . Interfaces ;
3+ using TUnit . TestProject . Attributes ;
4+
5+ namespace TUnit . TestProject . Bugs . _2955 ;
6+
7+ // Reproducing the issue from GitHub issue #2955
8+ // https://github.com/thomhurst/TUnit/issues/2955
9+
10+ public class Data1 : IAsyncInitializer
11+ {
12+ public string Value { get ; set ; } = string . Empty ;
13+
14+ public Task InitializeAsync ( )
15+ {
16+ Value = "Data1 Initialized" ;
17+ Console . WriteLine ( $ "Data1 InitializeAsync called - Value: { Value } ") ;
18+ return Task . CompletedTask ;
19+ }
20+ }
21+
22+ public class Data2 : IAsyncInitializer
23+ {
24+ [ ClassDataSource < Data1 > ]
25+ public required Data1 Data1 { get ; init ; }
26+
27+ public string Value { get ; set ; } = string . Empty ;
28+
29+ public virtual Task InitializeAsync ( )
30+ {
31+ // This should be called after Data1 has been injected and initialized
32+ Value = $ "Data2 Initialized (Data1: { Data1 ? . Value ?? "NULL" } )";
33+ Console . WriteLine ( $ "Data2 InitializeAsync called - Value: { Value } , Data1: { Data1 ? . Value ?? "NULL" } ") ;
34+ return Task . CompletedTask ;
35+ }
36+ }
37+
38+ // Data3 inherits from Data2, so it should inherit the Data1 property with its ClassDataSource attribute
39+ public class Data3 : Data2
40+ {
41+ public override Task InitializeAsync ( )
42+ {
43+ // This should be called after Data1 has been injected and initialized
44+ Value = $ "Data3 Initialized (Data1: { Data1 ? . Value ?? "NULL" } )";
45+ Console . WriteLine ( $ "Data3 InitializeAsync called - Value: { Value } , Data1: { Data1 ? . Value ?? "NULL" } ") ;
46+ return Task . CompletedTask ;
47+ }
48+ }
49+
50+ [ EngineTest ( ExpectedResult . Pass ) ]
51+ public class InheritedDataSourceTests
52+ {
53+ [ ClassDataSource < Data3 > ( Shared = SharedType . PerTestSession ) ]
54+ public required Data3 Data3 { get ; init ; }
55+
56+ [ Test ]
57+ public async Task Test_InheritedPropertyWithDataSource_ShouldBeInjected ( )
58+ {
59+ // The bug is that Data1 property (inherited from Data2) is not being injected
60+ // when Data3 is used as a ClassDataSource
61+
62+ Console . WriteLine ( $ "Test - Data3.Value: { Data3 . Value } ") ;
63+ Console . WriteLine ( $ "Test - Data3.Data1: { Data3 . Data1 } ") ;
64+ Console . WriteLine ( $ "Test - Data3.Data1?.Value: { Data3 . Data1 ? . Value } ") ;
65+
66+ // This assertion should pass but currently fails with the bug
67+ await Assert . That ( Data3 . Data1 ) . IsNotNull ( ) ;
68+ await Assert . That ( Data3 . Data1 . Value ) . IsEqualTo ( "Data1 Initialized" ) ;
69+ await Assert . That ( Data3 . Value ) . Contains ( "Data1: Data1 Initialized" ) ;
70+ }
71+
72+ [ Test ]
73+ [ ClassDataSource < Data2 > ]
74+ public async Task Test_DirectDataSource_WorksCorrectly ( Data2 data2 )
75+ {
76+ // This test uses Data2 directly (not through inheritance) and should work
77+ // The framework should inject Data1 into Data2 directly
78+
79+ // This should work because Data2's properties are defined directly on it
80+ await Assert . That ( data2 . Data1 ) . IsNotNull ( ) ;
81+ await Assert . That ( data2 . Data1 . Value ) . IsEqualTo ( "Data1 Initialized" ) ;
82+ await Assert . That ( data2 . Value ) . Contains ( "Data1: Data1 Initialized" ) ;
83+ }
84+ }
85+
86+ // Additional test case with multiple levels of inheritance
87+ public class BaseDataWithSource
88+ {
89+ [ ClassDataSource < Data1 > ]
90+ public required Data1 BaseData1 { get ; init ; }
91+ }
92+
93+ public class MiddleDataWithSource : BaseDataWithSource
94+ {
95+ [ ClassDataSource < Data2 > ]
96+ public required Data2 MiddleData2 { get ; init ; }
97+ }
98+
99+ public class DerivedDataWithSource : MiddleDataWithSource
100+ {
101+ public string DerivedValue { get ; set ; } = "Derived" ;
102+ }
103+
104+ [ EngineTest ( ExpectedResult . Pass ) ]
105+ public class MultiLevelInheritanceTests
106+ {
107+ [ ClassDataSource < DerivedDataWithSource > ]
108+ public required DerivedDataWithSource DerivedData { get ; init ; }
109+
110+ [ Test ]
111+ public async Task Test_MultiLevelInheritance_AllDataSourcesShouldBeInjected ( )
112+ {
113+ // Both BaseData1 and MiddleData2 should be injected even though they're in base classes
114+ await Assert . That ( DerivedData . BaseData1 ) . IsNotNull ( ) ;
115+ await Assert . That ( DerivedData . BaseData1 . Value ) . IsEqualTo ( "Data1 Initialized" ) ;
116+
117+ await Assert . That ( DerivedData . MiddleData2 ) . IsNotNull ( ) ;
118+ await Assert . That ( DerivedData . MiddleData2 . Data1 ) . IsNotNull ( ) ;
119+ }
120+ }
0 commit comments