Skip to content

Commit 6de7d3c

Browse files
authored
Test | Convert DateTimeVariantTests to xunit (#4196)
1 parent 97b2c47 commit 6de7d3c

6 files changed

Lines changed: 1303 additions & 2550 deletions

File tree

.github/instructions/testing.instructions.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,38 @@ Extended assertions for SqlClient:
321321
AssertExtensions.ThrowsContains<SqlException>(() => action(), "expected message");
322322
```
323323

324+
### RAII Database Object Classes
325+
When writing manual integration tests that require transient database objects, use the RAII classes from `Microsoft.Data.SqlClient.Tests.Common.Fixtures.DatabaseObjects` instead of manually writing `try/finally` blocks with DDL `DROP`/`CREATE` statements.
326+
327+
**Available classes:**
328+
329+
| Class | SQL generated | Example definition argument |
330+
|-------|--------------|----------------------------|
331+
| `Table` | `CREATE TABLE {Name} {definition}` | `"(Id INT, Value NVARCHAR(100))"` |
332+
| `StoredProcedure` | `CREATE PROCEDURE {Name} {definition}` | `"AS BEGIN SELECT 1 END"` |
333+
| `UserDefinedType` | `CREATE TYPE [dbo].{Name} AS {definition}` | `"TABLE (f1 INT)"` |
334+
335+
Each class generates a unique object name from the given prefix (incorporating a timestamp-based GUID, username, and machine name), creates the object on construction (requiring the connection to already be open), and drops it when disposed. The generated name is available via the `.Name` property.
336+
337+
**Pattern:**
338+
```csharp
339+
using SqlConnection conn = new(DataTestUtility.TCPConnectionString);
340+
conn.Open();
341+
342+
using Table testTable = new(conn, "MyTable", "(Id INT, Name NVARCHAR(100))");
343+
using StoredProcedure proc = new(conn, "MyProc", $"AS BEGIN SELECT * FROM {testTable.Name} END");
344+
345+
using SqlCommand cmd = conn.CreateCommand();
346+
cmd.CommandText = proc.Name;
347+
cmd.CommandType = CommandType.StoredProcedure;
348+
// ... objects are automatically dropped when the scope ends
349+
```
350+
351+
**Rules:**
352+
- Open the connection **before** constructing any database object (the constructor executes DDL immediately)
353+
- When objects depend on each other (e.g., a stored procedure that references a table), declare the dependent object **last** so it is disposed first — `using` declarations are disposed in reverse order
354+
- Use the `.Name` property directly wherever you need to reference the object in SQL; for `UserDefinedType` this already includes the `[dbo].` schema prefix, making it suitable for use as a TVP `TypeName`
355+
324356
## Code Coverage
325357

326358
### Running with Coverage

src/Microsoft.Data.SqlClient/tests/Common/DisposableArray.cs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,16 +60,32 @@ public T this[int i]
6060

6161
/// <summary>
6262
/// Disposes all elements in the current instance. Each element will be checked for
63-
/// <c>null</c> before disposing it.
63+
/// <c>null</c> before disposing it. All elements are disposed even if earlier disposals
64+
/// throw; any exceptions are collected and rethrown as an <see cref="AggregateException"/>
65+
/// after all elements have been attempted.
6466
/// </summary>
6567
public void Dispose()
6668
{
69+
List<Exception>? exceptions = null;
70+
6771
foreach (T element in _elements)
6872
{
69-
element?.Dispose();
73+
try
74+
{
75+
element?.Dispose();
76+
}
77+
catch (Exception ex)
78+
{
79+
(exceptions ??= new List<Exception>()).Add(ex);
80+
}
7081
}
7182

7283
GC.SuppressFinalize(this);
84+
85+
if (exceptions is not null)
86+
{
87+
throw new AggregateException(exceptions);
88+
}
7389
}
7490

7591
/// <inheritdoc/>

src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTests.csproj

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,6 @@
206206
<Compile Include="SQL\MARSTest\MARSTest.cs" />
207207
<Compile Include="SQL\MirroringTest\ConnectionOnMirroringTest.cs" />
208208
<Compile Include="SQL\ParallelTransactionsTest\ParallelTransactionsTest.cs" />
209-
<Compile Include="SQL\ParameterTest\DateTimeVariantTest.cs" />
210209
<Compile Include="SQL\ParameterTest\ParametersTest.cs" />
211210
<Compile Include="SQL\ParameterTest\SqlAdapterUpdateBatch.cs" />
212211
<Compile Include="SQL\ParameterTest\SteAttribute.cs" />
@@ -262,10 +261,6 @@
262261
CopyToOutputDirectory="PreserveNewest" />
263262

264263
<!-- Baseline files for individual test groups -->
265-
<Content Include="SQL\ParameterTest\DateTimeVariant.bsl">
266-
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
267-
<Link>DateTimeVariant.bsl</Link>
268-
</Content>
269264
<Content Include="SQL\ParameterTest\StreamInputParameter_DebugMode.bsl">
270265
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
271266
<Link>StreamInputParameter_DebugMode.bsl</Link>

0 commit comments

Comments
 (0)