1
+ using TUnit . TestProject . Attributes ;
2
+
3
+ namespace TUnit . TestProject . InheritanceSharedTypeRepro ;
4
+
5
+ // Simulating the user's container wrappers
6
+ public class PostgreSqlContainerWrapper : IDisposable , IAsyncDisposable
7
+ {
8
+ public bool IsDisposed { get ; private set ; }
9
+ public string InstanceId { get ; } = Guid . NewGuid ( ) . ToString ( ) ;
10
+
11
+ public void Dispose ( )
12
+ {
13
+ IsDisposed = true ;
14
+ Console . WriteLine ( $ "PostgreSQL Container { InstanceId } disposed (sync)") ;
15
+ }
16
+
17
+ public ValueTask DisposeAsync ( )
18
+ {
19
+ IsDisposed = true ;
20
+ Console . WriteLine ( $ "PostgreSQL Container { InstanceId } disposed (async)") ;
21
+ return default ;
22
+ }
23
+ }
24
+
25
+ public class RabbitMqContainerWrapper : IDisposable , IAsyncDisposable
26
+ {
27
+ public bool IsDisposed { get ; private set ; }
28
+ public string InstanceId { get ; } = Guid . NewGuid ( ) . ToString ( ) ;
29
+
30
+ public void Dispose ( )
31
+ {
32
+ IsDisposed = true ;
33
+ Console . WriteLine ( $ "RabbitMQ Container { InstanceId } disposed (sync)") ;
34
+ }
35
+
36
+ public ValueTask DisposeAsync ( )
37
+ {
38
+ IsDisposed = true ;
39
+ Console . WriteLine ( $ "RabbitMQ Container { InstanceId } disposed (async)") ;
40
+ return default ;
41
+ }
42
+ }
43
+
44
+ // Base application testing server (like in the user's example)
45
+ public class BaseApplicationTestingServer < T >
46
+ {
47
+ // Base functionality
48
+ }
49
+
50
+ // The working scenario - containers defined directly on TestingServer
51
+ public class TestingServerWorking : BaseApplicationTestingServer < object >
52
+ {
53
+ [ ClassDataSource < PostgreSqlContainerWrapper > ( Shared = SharedType . PerTestSession ) ]
54
+ public required PostgreSqlContainerWrapper PostgresContainerWrapper { get ; set ; } = new ( ) ;
55
+
56
+ [ ClassDataSource < RabbitMqContainerWrapper > ( Shared = SharedType . PerTestSession ) ]
57
+ public required RabbitMqContainerWrapper RabbitContainerWrapper { get ; set ; } = new ( ) ;
58
+ }
59
+
60
+ // The broken scenario - containers defined on intermediate base class
61
+ public abstract class ModuleTestingServer : BaseApplicationTestingServer < object >
62
+ {
63
+ [ ClassDataSource < PostgreSqlContainerWrapper > ( Shared = SharedType . PerTestSession ) ]
64
+ public required PostgreSqlContainerWrapper PostgresContainerWrapper { get ; set ; } = new ( ) ;
65
+
66
+ [ ClassDataSource < RabbitMqContainerWrapper > ( Shared = SharedType . PerTestSession ) ]
67
+ public required RabbitMqContainerWrapper RabbitContainerWrapper { get ; set ; } = new ( ) ;
68
+ }
69
+
70
+ public class TestingServerBroken : ModuleTestingServer
71
+ {
72
+ // Inherits the ClassDataSource properties from ModuleTestingServer
73
+ }
74
+
75
+ // Test classes for the working scenario
76
+ [ EngineTest ( ExpectedResult . Pass ) ]
77
+ public class WorkingTestClass1
78
+ {
79
+ [ ClassDataSource < TestingServerWorking > ( Shared = SharedType . PerClass ) ]
80
+ public required TestingServerWorking TestingServer { get ; set ; } = default ! ;
81
+
82
+ [ Test , NotInParallel ( Order = 1 ) ]
83
+ public async Task Test1 ( )
84
+ {
85
+ Console . WriteLine ( $ "WorkingTestClass1.Test1 - PostgreSQL: { TestingServer . PostgresContainerWrapper . InstanceId } , RabbitMQ: { TestingServer . RabbitContainerWrapper . InstanceId } ") ;
86
+
87
+ await Assert . That ( TestingServer . PostgresContainerWrapper . IsDisposed ) . IsFalse ( ) ;
88
+ await Assert . That ( TestingServer . RabbitContainerWrapper . IsDisposed ) . IsFalse ( ) ;
89
+ }
90
+
91
+ [ Test , NotInParallel ( Order = 2 ) ]
92
+ public async Task Test2 ( )
93
+ {
94
+ Console . WriteLine ( $ "WorkingTestClass1.Test2 - PostgreSQL: { TestingServer . PostgresContainerWrapper . InstanceId } , RabbitMQ: { TestingServer . RabbitContainerWrapper . InstanceId } ") ;
95
+
96
+ await Assert . That ( TestingServer . PostgresContainerWrapper . IsDisposed ) . IsFalse ( ) ;
97
+ await Assert . That ( TestingServer . RabbitContainerWrapper . IsDisposed ) . IsFalse ( ) ;
98
+ }
99
+ }
100
+
101
+ [ EngineTest ( ExpectedResult . Pass ) ]
102
+ public class WorkingTestClass2
103
+ {
104
+ [ ClassDataSource < TestingServerWorking > ( Shared = SharedType . PerClass ) ]
105
+ public required TestingServerWorking TestingServer { get ; set ; } = default ! ;
106
+
107
+ [ Test , NotInParallel ( Order = 3 ) ]
108
+ public async Task Test3 ( )
109
+ {
110
+ Console . WriteLine ( $ "WorkingTestClass2.Test3 - PostgreSQL: { TestingServer . PostgresContainerWrapper . InstanceId } , RabbitMQ: { TestingServer . RabbitContainerWrapper . InstanceId } ") ;
111
+
112
+ await Assert . That ( TestingServer . PostgresContainerWrapper . IsDisposed ) . IsFalse ( ) ;
113
+ await Assert . That ( TestingServer . RabbitContainerWrapper . IsDisposed ) . IsFalse ( ) ;
114
+ }
115
+
116
+ [ Test , NotInParallel ( Order = 4 ) ]
117
+ public async Task Test4 ( )
118
+ {
119
+ Console . WriteLine ( $ "WorkingTestClass2.Test4 - PostgreSQL: { TestingServer . PostgresContainerWrapper . InstanceId } , RabbitMQ: { TestingServer . RabbitContainerWrapper . InstanceId } ") ;
120
+
121
+ await Assert . That ( TestingServer . PostgresContainerWrapper . IsDisposed ) . IsFalse ( ) ;
122
+ await Assert . That ( TestingServer . RabbitContainerWrapper . IsDisposed ) . IsFalse ( ) ;
123
+ }
124
+ }
125
+
126
+ // Test classes for the broken scenario
127
+ [ EngineTest ( ExpectedResult . Pass ) ]
128
+ public class BrokenTestClass1
129
+ {
130
+ [ ClassDataSource < TestingServerBroken > ( Shared = SharedType . PerClass ) ]
131
+ public required TestingServerBroken TestingServer { get ; set ; } = default ! ;
132
+
133
+ [ Test , NotInParallel ( Order = 5 ) ]
134
+ public async Task Test5 ( )
135
+ {
136
+ Console . WriteLine ( $ "BrokenTestClass1.Test5 - PostgreSQL: { TestingServer . PostgresContainerWrapper . InstanceId } , RabbitMQ: { TestingServer . RabbitContainerWrapper . InstanceId } ") ;
137
+
138
+ await Assert . That ( TestingServer . PostgresContainerWrapper . IsDisposed ) . IsFalse ( ) ;
139
+ await Assert . That ( TestingServer . RabbitContainerWrapper . IsDisposed ) . IsFalse ( ) ;
140
+ }
141
+
142
+ [ Test , NotInParallel ( Order = 6 ) ]
143
+ public async Task Test6 ( )
144
+ {
145
+ Console . WriteLine ( $ "BrokenTestClass1.Test6 - PostgreSQL: { TestingServer . PostgresContainerWrapper . InstanceId } , RabbitMQ: { TestingServer . RabbitContainerWrapper . InstanceId } ") ;
146
+
147
+ await Assert . That ( TestingServer . PostgresContainerWrapper . IsDisposed ) . IsFalse ( ) ;
148
+ await Assert . That ( TestingServer . RabbitContainerWrapper . IsDisposed ) . IsFalse ( ) ;
149
+ }
150
+ }
151
+
152
+ [ EngineTest ( ExpectedResult . Pass ) ]
153
+ public class BrokenTestClass2
154
+ {
155
+ [ ClassDataSource < TestingServerBroken > ( Shared = SharedType . PerClass ) ]
156
+ public required TestingServerBroken TestingServer { get ; set ; } = default ! ;
157
+
158
+ [ Test , NotInParallel ( Order = 7 ) ]
159
+ public async Task Test7 ( )
160
+ {
161
+ Console . WriteLine ( $ "BrokenTestClass2.Test7 - PostgreSQL: { TestingServer . PostgresContainerWrapper . InstanceId } , RabbitMQ: { TestingServer . RabbitContainerWrapper . InstanceId } ") ;
162
+
163
+ await Assert . That ( TestingServer . PostgresContainerWrapper . IsDisposed ) . IsFalse ( ) ;
164
+ await Assert . That ( TestingServer . RabbitContainerWrapper . IsDisposed ) . IsFalse ( ) ;
165
+ }
166
+
167
+ [ Test , NotInParallel ( Order = 8 ) ]
168
+ public async Task Test8 ( )
169
+ {
170
+ Console . WriteLine ( $ "BrokenTestClass2.Test8 - PostgreSQL: { TestingServer . PostgresContainerWrapper . InstanceId } , RabbitMQ: { TestingServer . RabbitContainerWrapper . InstanceId } ") ;
171
+
172
+ await Assert . That ( TestingServer . PostgresContainerWrapper . IsDisposed ) . IsFalse ( ) ;
173
+ await Assert . That ( TestingServer . RabbitContainerWrapper . IsDisposed ) . IsFalse ( ) ;
174
+ }
175
+ }
0 commit comments