Browse Source

Tests | Move various unit tests to UnitTests project (#3458)

* Move SqlVectorTest, adjust namespace

* Replace LocalAppContextSwitchesTests

* Move SqlBufferTests

* Remove unnecessary reflection from SqlBufferTests

* Add descriptions to SqlBufferTests

* Move SqlCommandSetTest

* Remove unnecessary reflection from SqlCommandSetTest

* Act on messages

* Add descriptions to SqlCommandSetTests

* Rename SqlBufferTests to align with standard

* Adhere to project code style: namespace statements

* Remove redundant using statement

* Add missing license statement

* Remove all internal reflection on SqlCommandSetTest

* Remove unnecessary validation logic (and covering test)
pull/2572/merge
Edward Neal 3 weeks ago
committed by GitHub
parent
commit
ad01286287
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 22
      src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommandSet.cs
  2. 34
      src/Microsoft.Data.SqlClient/tests/FunctionalTests/LocalAppContextSwitchesTests.cs
  3. 3
      src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.FunctionalTests.csproj
  4. 253
      src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlBufferTests.cs
  5. 200
      src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlCommandSetTest.cs
  6. 32
      src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/LocalAppContextSwitchesTest.cs
  7. 148
      src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/SqlBufferTest.cs
  8. 137
      src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/SqlCommandSetTest.cs
  9. 3
      src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlTypes/SqlJsonTest.cs
  10. 4
      src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlTypes/SqlVectorTest.cs

22
src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommandSet.cs

@ -30,7 +30,7 @@ namespace Microsoft.Data.SqlClient
_commandList = new List<SqlBatchCommand>();
}
private SqlCommand BatchCommand
internal SqlCommand BatchCommand
{
get
{
@ -45,7 +45,7 @@ namespace Microsoft.Data.SqlClient
internal int CommandCount => CommandList.Count;
private List<SqlBatchCommand> CommandList
internal List<SqlBatchCommand> CommandList
{
get
{
@ -98,24 +98,16 @@ namespace Microsoft.Data.SqlClient
{
ADP.CheckArgumentNull(command, nameof(command));
SqlClientEventSource.Log.TryTraceEvent("SqlCommandSet.Append | API | Object Id {0}, Command '{1}', Parameter Count {2}", ObjectID, command.ObjectID, command.Parameters.Count);
// SqlCommandSet only supports commands of type Text or StoredProcedure. This aligns with SqlCommand (validated by its CommandType setter.)
Debug.Assert(command.CommandType is CommandType.Text or CommandType.StoredProcedure);
string cmdText = command.CommandText;
if (string.IsNullOrEmpty(cmdText))
{
throw ADP.CommandTextRequired(nameof(Append));
}
CommandType commandType = command.CommandType;
switch (commandType)
{
case CommandType.Text:
case CommandType.StoredProcedure:
break;
case CommandType.TableDirect:
throw SQL.NotSupportedCommandType(commandType);
default:
throw ADP.InvalidCommandType(commandType);
}
SqlParameterCollection parameters = null;
SqlParameterCollection collection = command.Parameters;
@ -279,7 +271,7 @@ namespace Microsoft.Data.SqlClient
internal int GetParameterCount(int commandIndex)
=> CommandList[commandIndex].Parameters.Count;
private void ValidateCommandBehavior(string method, CommandBehavior behavior)
internal void ValidateCommandBehavior(string method, CommandBehavior behavior)
{
if (0 != (behavior & ~(CommandBehavior.SequentialAccess | CommandBehavior.CloseConnection)))
{

34
src/Microsoft.Data.SqlClient/tests/FunctionalTests/LocalAppContextSwitchesTests.cs

@ -1,34 +0,0 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Reflection;
using Xunit;
namespace Microsoft.Data.SqlClient.Tests
{
public class LocalAppContextSwitchesTests
{
[Theory]
[InlineData("LegacyRowVersionNullBehavior", false)]
[InlineData("SuppressInsecureTlsWarning", false)]
[InlineData("MakeReadAsyncBlocking", false)]
[InlineData("UseMinimumLoginTimeout", true)]
[InlineData("LegacyVarTimeZeroScaleBehaviour", true)]
[InlineData("UseCompatibilityProcessSni", false)]
[InlineData("UseCompatibilityAsyncBehaviour", false)]
[InlineData("UseConnectionPoolV2", false)]
#if NETFRAMEWORK
[InlineData("DisableTnirByDefault", false)]
#endif
public void DefaultSwitchValue(string property, bool expectedDefaultValue)
{
var switchesType = typeof(SqlCommand).Assembly.GetType("Microsoft.Data.SqlClient.LocalAppContextSwitches");
var switchValue = (bool)switchesType.GetProperty(property, BindingFlags.Public | BindingFlags.Static).GetValue(null);
Assert.Equal(expectedDefaultValue, switchValue);
}
}
}

3
src/Microsoft.Data.SqlClient/tests/FunctionalTests/Microsoft.Data.SqlClient.FunctionalTests.csproj

@ -30,10 +30,7 @@
<Compile Include="MultipartIdentifierTests.cs" />
<Compile Include="MultiplexerTests.cs" />
<Compile Include="SqlAuthenticationProviderTest.cs" />
<Compile Include="SqlBufferTests.cs" />
<Compile Include="SqlClientLoggerTest.cs" />
<Compile Include="SqlCommandSetTest.cs" />
<Compile Include="LocalAppContextSwitchesTests.cs" />
<Compile Include="SqlConfigurableRetryLogicTest.cs" />
<Compile Include="SqlCommandBuilderTest.cs" />
<Compile Include="SqlBulkCopyTest.cs" />

253
src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlBufferTests.cs

@ -1,253 +0,0 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using System.Data.SqlTypes;
using System.Linq;
using System.Reflection;
using Xunit;
namespace Microsoft.Data.SqlClient.Tests
{
public sealed class SqlBufferTests
{
static SqlBufferTests()
{
const string sqlBufferTypeFullName = "Microsoft.Data.SqlClient.SqlBuffer";
const string storageTypeName = nameof(SqlBufferProxy.StorageType);
var assembly = typeof(SqlClientFactory).Assembly;
_sqlBufferType = assembly.GetType(sqlBufferTypeFullName)
?? throw new Exception($"Type not found [{sqlBufferTypeFullName}]");
_storageTypeType = _sqlBufferType.GetNestedTypes(BindingFlags.NonPublic)
.FirstOrDefault(x => x.Name == storageTypeName)
?? throw new Exception($"Type not found [{sqlBufferTypeFullName}+{storageTypeName}]");
}
private static readonly Type _sqlBufferType;
private static readonly Type _storageTypeType;
private readonly SqlBufferProxy _target = new();
public static IEnumerable<object[]> GetStorageTypeValues()
{
#if NET
return Enum.GetValues<SqlBufferProxy.StorageType>()
.Select(x => new object[] { x });
#else
return Enum.GetValues(typeof(SqlBufferProxy.StorageType))
.OfType<SqlBufferProxy.StorageType>()
.Select(x => new object[] { x });
#endif
}
[Theory]
[MemberData(nameof(GetStorageTypeValues))]
public void StorageTypeInProxyShouldHaveTheSameValueAsOriginal(SqlBufferProxy.StorageType expected)
{
var originalEnumName = Enum.GetName(_storageTypeType, (int)expected);
Assert.Equal(expected.ToString(), originalEnumName);
}
[Fact]
public void GuidShouldThrowWhenSqlGuidNullIsSet()
{
_target.SqlGuid = SqlGuid.Null;
Assert.Throws<SqlNullValueException>(() => _target.Guid);
}
[Theory]
[InlineData(SqlBufferProxy.StorageType.Guid)]
[InlineData(SqlBufferProxy.StorageType.SqlGuid)]
public void GuidShouldThrowWhenSetToNullOfTypeIsCalled(SqlBufferProxy.StorageType storageType)
{
_target.SetToNullOfType(storageType);
Assert.Throws<SqlNullValueException>(() => _target.Guid);
}
[Fact]
public void GuidShouldReturnWhenGuidIsSet()
{
var expected = Guid.NewGuid();
_target.Guid = expected;
Assert.Equal(expected, _target.Guid);
}
[Fact]
public void GuidShouldReturnExpectedWhenSqlGuidIsSet()
{
var expected = Guid.NewGuid();
_target.SqlGuid = expected;
Assert.Equal(expected, _target.Guid);
}
[Theory]
[InlineData(SqlBufferProxy.StorageType.Guid)]
[InlineData(SqlBufferProxy.StorageType.SqlGuid)]
public void SqlGuidShouldReturnSqlNullWhenSetToNullOfTypeIsCalled(SqlBufferProxy.StorageType storageType)
{
_target.SetToNullOfType(storageType);
Assert.Equal(SqlGuid.Null, _target.SqlGuid);
}
[Fact]
public void SqlGuidShouldReturnSqlGuidNullWhenSqlGuidNullIsSet()
{
_target.SqlGuid = SqlGuid.Null;
Assert.Equal(SqlGuid.Null, _target.SqlGuid);
}
[Fact]
public void SqlGuidShouldReturnExpectedWhenGuidIsSet()
{
var guid = Guid.NewGuid();
SqlGuid expected = guid;
_target.Guid = guid;
Assert.Equal(expected, _target.SqlGuid);
}
[Fact]
public void SqlGuidShouldReturnExpectedWhenSqlGuidIsSet()
{
SqlGuid expected = Guid.NewGuid();
_target.SqlGuid = expected;
Assert.Equal(expected, _target.SqlGuid);
}
[Fact]
public void SqlValueShouldReturnExpectedWhenGuidIsSet()
{
var guid = Guid.NewGuid();
SqlGuid expected = guid;
_target.Guid = guid;
Assert.Equal(expected, _target.SqlValue);
}
[Fact]
public void SqlValueShouldReturnExpectedWhenSqlGuidIsSet()
{
SqlGuid expected = Guid.NewGuid();
_target.SqlGuid = expected;
Assert.Equal(expected, _target.SqlValue);
}
public sealed class SqlBufferProxy
{
public enum StorageType
{
Empty = 0,
Boolean,
Byte,
DateTime,
Decimal,
Double,
Int16,
Int32,
Int64,
Guid,
Money,
Single,
String,
SqlBinary,
SqlCachedBuffer,
SqlGuid,
SqlXml,
Date,
DateTime2,
DateTimeOffset,
Time,
}
private static readonly PropertyInfo _guidProperty;
private static readonly PropertyInfo _sqlGuidProperty;
private static readonly PropertyInfo _sqlValueProperty;
private static readonly MethodInfo _setToNullOfTypeMethod;
private readonly object _instance;
static SqlBufferProxy()
{
var flags = BindingFlags.NonPublic | BindingFlags.Instance;
_guidProperty = _sqlBufferType.GetProperty(nameof(Guid), flags);
_sqlGuidProperty = _sqlBufferType.GetProperty(nameof(SqlGuid), flags);
_sqlValueProperty = _sqlBufferType.GetProperty(nameof(SqlValue), flags);
_setToNullOfTypeMethod = _sqlBufferType.GetMethod(nameof(SetToNullOfType), flags);
}
public SqlBufferProxy()
{
_instance = Activator.CreateInstance(_sqlBufferType, true);
}
public Guid Guid
{
get => GetPropertyValue<Guid>(_guidProperty);
set => SetPropertyValue(_guidProperty, value);
}
public SqlGuid SqlGuid
{
get => GetPropertyValue<SqlGuid>(_sqlGuidProperty);
set => SetPropertyValue(_sqlGuidProperty, value);
}
public object SqlValue
{
get => GetPropertyValue<object>(_sqlValueProperty);
}
public void SetToNullOfType(StorageType storageType)
{
#if NET
_setToNullOfTypeMethod
.Invoke(_instance, BindingFlags.DoNotWrapExceptions, null, new object[] { (int)storageType }, null);
#else
_setToNullOfTypeMethod.Invoke(_instance, new object[] { (int)storageType });
#endif
}
private T GetPropertyValue<T>(PropertyInfo property)
{
#if NET
return (T)property.GetValue(_instance, BindingFlags.DoNotWrapExceptions, null, null, null);
#else
try
{
return (T)property.GetValue(_instance);
}
catch (TargetInvocationException e)
{
throw e.InnerException!;
}
#endif
}
private void SetPropertyValue(PropertyInfo property, object value)
{
#if NET
property.SetValue(_instance, value, BindingFlags.DoNotWrapExceptions, null, null, null);
#else
try
{
property.SetValue(_instance, value);
}
catch (TargetInvocationException e)
{
throw e.InnerException!;
}
#endif
}
}
}
}

200
src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlCommandSetTest.cs

@ -1,200 +0,0 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Reflection;
using Xunit;
namespace Microsoft.Data.SqlClient.Tests
{
public class SqlCommandSetTest
{
private static Assembly mds = Assembly.GetAssembly(typeof(SqlConnection));
[Theory]
[InlineData("BatchCommand")]
[InlineData("CommandList")]
public void GetDisposedProperty_Throws(string propertyName)
{
var cmdSet = CreateInstance();
CallMethod(cmdSet, "Dispose");
Exception ex = GetProperty_Throws(cmdSet, propertyName);
VerifyException<ObjectDisposedException>(ex, "disposed");
}
[Fact]
public void AppendCommandWithEmptyString_Throws()
{
var cmdSet = CreateInstance();
SqlCommand cmd = new SqlCommand("");
Exception ex = CallMethod_Throws(cmdSet, "Append", cmd);
VerifyException<InvalidOperationException>(ex, "CommandText property has not been initialized");
}
public static IEnumerable<object[]> CommandTypeData()
{
return new object[][]
{
new object[] { CommandType.TableDirect },
new object[] { (CommandType)5 }
};
}
[Theory]
[MemberData(
nameof(CommandTypeData)
#if NETFRAMEWORK
// .NET Framework puts system enums in something called the Global
// Assembly Cache (GAC), and xUnit refuses to serialize enums that
// live there. So for .NET Framework, we disable enumeration of the
// test data to avoid warnings on the console when running tests.
, DisableDiscoveryEnumeration = true
#endif
)]
public void AppendBadCommandType_Throws(CommandType commandType)
{
var cmdSet = CreateInstance();
SqlCommand cmd = GenerateBadCommand(commandType);
Exception ex = CallMethod_Throws(cmdSet, "Append", cmd);
VerifyException<ArgumentOutOfRangeException>(ex, "CommandType");
}
[Fact]
public void AppendBadParameterName_Throws()
{
var cmdSet = CreateInstance();
SqlCommand cmd = new SqlCommand("Test");
cmd.CommandType = CommandType.Text;
cmd.Parameters.Add(new SqlParameter("Test1;=", "1"));
Exception ex = CallMethod_Throws(cmdSet, "Append", cmd);
VerifyException<ArgumentException>(ex, "not valid");
}
[Theory]
[InlineData(new byte[] { 1, 2, 3 })]
[InlineData(new char[] { '1', '2', '3' })]
public void AppendParameterArrayWithSize(object array)
{
var cmdSet = CreateInstance();
SqlCommand cmd = new SqlCommand("Test");
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter parameter = new SqlParameter("@array", array);
parameter.Size = 2;
cmd.Parameters.Add(parameter);
CallMethod(cmdSet, "Append", cmd);
object p = CallMethod(cmdSet, "GetParameter", 0, 0);
SqlParameter result = p as SqlParameter;
Assert.NotNull(result);
Assert.Equal("@array", result.ParameterName);
Assert.Equal(2, result.Size);
}
[Fact]
public void GetParameter()
{
var cmdSet = CreateInstance();
SqlCommand cmd = new SqlCommand("Test");
cmd.CommandType = CommandType.Text;
cmd.Parameters.Add(new SqlParameter("@text", "value"));
CallMethod(cmdSet, "Append", cmd);
object p = CallMethod(cmdSet, "GetParameter", 0, 0);
SqlParameter result = p as SqlParameter;
Assert.NotNull(result);
Assert.Equal("@text", result.ParameterName);
Assert.Equal("value", (string)result.Value);
}
[Fact]
public void GetParameterCount()
{
var commandSetType = mds.GetType("Microsoft.Data.SqlClient.SqlCommandSet");
var cmdSet = Activator.CreateInstance(commandSetType, true);
SqlCommand cmd = new SqlCommand("Test");
cmd.CommandType = CommandType.Text;
cmd.Parameters.Add(new SqlParameter("@abc", "1"));
cmd.Parameters.Add(new SqlParameter("@test", "2"));
commandSetType.GetMethod("Append", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).Invoke(cmdSet, new object[] { cmd });
int index = 0;
int count = (int)commandSetType.GetMethod("GetParameterCount", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).Invoke(cmdSet, new object[] { index });
Assert.Equal(2, count);
}
[Fact]
public void InvalidCommandBehaviorValidateCommandBehavior_Throws()
{
var cmdSet = CreateInstance();
Exception ex = CallMethod_Throws(cmdSet, "ValidateCommandBehavior", "ExecuteNonQuery", (CommandBehavior)64);
VerifyException<ArgumentOutOfRangeException>(ex, "CommandBehavior");
}
[Fact]
public void NotSupportedCommandBehaviorValidateCommandBehavior_Throws()
{
var cmdSet = CreateInstance();
Exception ex = CallMethod_Throws(cmdSet, "ValidateCommandBehavior", "ExecuteNonQuery", CommandBehavior.KeyInfo);
VerifyException<ArgumentOutOfRangeException>(ex, "not supported");
}
#region private methods
private object CallMethod(object instance, string methodName, params object[] values)
{
var commandSetType = mds.GetType("Microsoft.Data.SqlClient.SqlCommandSet");
object returnValue = commandSetType.GetMethod(methodName, System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).Invoke(instance, values);
return returnValue;
}
private object CallMethod(object instance, string methodName)
{
var commandSetType = mds.GetType("Microsoft.Data.SqlClient.SqlCommandSet");
object returnValue = commandSetType.GetMethod(methodName, System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).Invoke(instance, new object[] { });
return returnValue;
}
private Exception CallMethod_Throws(object instance, string methodName, params object[] values)
{
var commandSetType = mds.GetType("Microsoft.Data.SqlClient.SqlCommandSet");
Exception ex = Assert.ThrowsAny<Exception>(() =>
{
commandSetType.GetMethod(methodName, System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).Invoke(instance, values);
});
return ex;
}
private object CreateInstance()
{
var commandSetType = mds.GetType("Microsoft.Data.SqlClient.SqlCommandSet");
object cmdSet = Activator.CreateInstance(commandSetType, true);
return cmdSet;
}
private Exception GetProperty_Throws(object instance, string propertyName)
{
var commandSetType = mds.GetType("Microsoft.Data.SqlClient.SqlCommandSet");
var cmdSet = instance;
Exception ex = Assert.ThrowsAny<Exception>(() =>
{
commandSetType.GetProperty(propertyName, System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).GetGetMethod(true).Invoke(cmdSet, new object[] { });
});
return ex;
}
private SqlCommand GenerateBadCommand(CommandType cType)
{
SqlCommand cmd = new SqlCommand("Test");
Type sqlCommandType = cmd.GetType();
// There's validation done on the CommandType property, but we need to create one that avoids the check for the test case.
sqlCommandType.GetField("_commandType", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(cmd, cType);
return cmd;
}
private void VerifyException<T>(Exception ex, string contains)
{
Assert.NotNull(ex);
Assert.IsType<T>(ex.InnerException);
Assert.Contains(contains, ex.InnerException.Message, StringComparison.OrdinalIgnoreCase);
}
#endregion
}
}

32
src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/LocalAppContextSwitchesTest.cs

@ -0,0 +1,32 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Xunit;
namespace Microsoft.Data.SqlClient.UnitTests;
/// <summary>
/// Provides unit tests for verifying the default values of all SqlClient-specific AppContext switches.
/// </summary>
public class LocalAppContextSwitchesTest
{
/// <summary>
/// Tests the default values of every AppContext switch used by SqlClient.
/// </summary>
[Fact]
public void TestDefaultAppContextSwitchValues()
{
Assert.False(LocalAppContextSwitches.LegacyRowVersionNullBehavior);
Assert.False(LocalAppContextSwitches.SuppressInsecureTlsWarning);
Assert.False(LocalAppContextSwitches.MakeReadAsyncBlocking);
Assert.True(LocalAppContextSwitches.UseMinimumLoginTimeout);
Assert.True(LocalAppContextSwitches.LegacyVarTimeZeroScaleBehaviour);
Assert.False(LocalAppContextSwitches.UseCompatibilityProcessSni);
Assert.False(LocalAppContextSwitches.UseCompatibilityAsyncBehaviour);
Assert.False(LocalAppContextSwitches.UseConnectionPoolV2);
#if NETFRAMEWORK
Assert.False(LocalAppContextSwitches.DisableTnirByDefault);
#endif
}
}

148
src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/SqlBufferTest.cs

@ -0,0 +1,148 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Data.SqlTypes;
using Xunit;
namespace Microsoft.Data.SqlClient.UnitTests;
/// <summary>
/// Tests that null and non-null values assigned to the SqlBuffer round-trip correctly to their CLR and their
/// their SqlTypes representations.
/// </summary>
/// <remarks>
/// Several methods in this class are internal. This is because their parameters are of SqlBuffer.StorageType,
/// which is non-public.
/// </remarks>
public sealed class SqlBufferTest
{
private readonly SqlBuffer _target = new();
/// <summary>
/// Verifies that if a SqlBuffer is directly assigned the value of SqlGuid.Null, accessing its Guid property
/// throws a SqlNullValueException.
/// </summary>
[Fact]
public void GuidShouldThrowWhenSqlGuidNullIsSet()
{
_target.SqlGuid = SqlGuid.Null;
Assert.Throws<SqlNullValueException>(() => _target.Guid);
}
/// <summary>
/// Verifies that if a SqlBuffer is set to null of type Guid or SqlGuid, accessing its Guid property throws
/// a SqlNullValueException.
/// </summary>
[Theory]
[InlineData(SqlBuffer.StorageType.Guid)]
[InlineData(SqlBuffer.StorageType.SqlGuid)]
internal void GuidShouldThrowWhenSetToNullOfTypeIsCalled(SqlBuffer.StorageType storageType)
{
_target.SetToNullOfType(storageType);
Assert.Throws<SqlNullValueException>(() => _target.Guid);
}
/// <summary>
/// Verifies that the Guid property round-trips correctly.
/// </summary>
[Fact]
public void GuidShouldReturnWhenGuidIsSet()
{
var expected = Guid.NewGuid();
_target.Guid = expected;
Assert.Equal(expected, _target.Guid);
}
/// <summary>
/// Verifies that the SqlGuid property round-trips to the Guid property correctly.
/// </summary>
[Fact]
public void GuidShouldReturnExpectedWhenSqlGuidIsSet()
{
var expected = Guid.NewGuid();
_target.SqlGuid = expected;
Assert.Equal(expected, _target.Guid);
}
/// <summary>
/// Verifies that if a SqlBuffer is set to null of type Guid or SqlGuid, accessing its SqlGuid property returns
/// SqlGuid.Null.
/// </summary>
[Theory]
[InlineData(SqlBuffer.StorageType.Guid)]
[InlineData(SqlBuffer.StorageType.SqlGuid)]
internal void SqlGuidShouldReturnSqlNullWhenSetToNullOfTypeIsCalled(SqlBuffer.StorageType storageType)
{
_target.SetToNullOfType(storageType);
Assert.Equal(SqlGuid.Null, _target.SqlGuid);
}
/// <summary>
/// Verifies that if a SqlBuffer is directly assigned the value of SqlGuid.Null, accessing its SqlGuid property
/// returns SqlGuid.Null.
/// </summary>
[Fact]
public void SqlGuidShouldReturnSqlGuidNullWhenSqlGuidNullIsSet()
{
_target.SqlGuid = SqlGuid.Null;
Assert.Equal(SqlGuid.Null, _target.SqlGuid);
}
/// <summary>
/// Verifies that the Guid property round-trips to the SqlGuid property correctly.
/// </summary>
[Fact]
public void SqlGuidShouldReturnExpectedWhenGuidIsSet()
{
var guid = Guid.NewGuid();
SqlGuid expected = guid;
_target.Guid = guid;
Assert.Equal(expected, _target.SqlGuid);
}
/// <summary>
/// Verifies that the SqlGuid property round-trips correctly.
/// </summary>
[Fact]
public void SqlGuidShouldReturnExpectedWhenSqlGuidIsSet()
{
SqlGuid expected = Guid.NewGuid();
_target.SqlGuid = expected;
Assert.Equal(expected, _target.SqlGuid);
}
/// <summary>
/// Verifies that the Guid property round-trips to the SqlValue property correctly.
/// </summary>
[Fact]
public void SqlValueShouldReturnExpectedWhenGuidIsSet()
{
var guid = Guid.NewGuid();
SqlGuid expected = guid;
_target.Guid = guid;
Assert.Equal(expected, _target.SqlValue);
}
/// <summary>
/// Verifies that the SqlGuid property round-trips to the SqlValue property correctly.
/// </summary>
[Fact]
public void SqlValueShouldReturnExpectedWhenSqlGuidIsSet()
{
SqlGuid expected = Guid.NewGuid();
_target.SqlGuid = expected;
Assert.Equal(expected, _target.SqlValue);
}
}

137
src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/SqlCommandSetTest.cs

@ -0,0 +1,137 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Data;
using Xunit;
namespace Microsoft.Data.SqlClient.UnitTests;
/// <summary>
/// Provides unit tests for verifying the behavior of the SqlCommandSet class.
/// </summary>
public class SqlCommandSetTest
{
/// <summary>
/// Verifies that key properties throw an ObjectDisposedException after the SqlCommandSet has been disposed.
/// </summary>
[Fact]
public void GetDisposedProperty_Throws()
{
SqlCommandSet cmdSet = new();
cmdSet.Dispose();
ObjectDisposedException ex = Assert.Throws<ObjectDisposedException>(() => _ = cmdSet.BatchCommand);
Assert.Contains("disposed", ex.Message, StringComparison.OrdinalIgnoreCase);
ex = Assert.Throws<ObjectDisposedException>(() => _ = cmdSet.CommandList);
Assert.Contains("disposed", ex.Message, StringComparison.OrdinalIgnoreCase);
}
/// <summary>
/// Verifies that adding a SqlCommand with an empty CommandText to a SqlCommandSet throws an InvalidOperationException.
/// </summary>
[Fact]
public void AppendCommandWithEmptyString_Throws()
{
SqlCommandSet cmdSet = new();
using SqlCommand cmd = new("");
InvalidOperationException ex = Assert.Throws<InvalidOperationException>(() => cmdSet.Append(cmd));
Assert.Contains("CommandText property has not been initialized", ex.Message, StringComparison.OrdinalIgnoreCase);
}
/// <summary>
/// Verifies that adding a SqlCommand containing a SqlParameter with an invalid name to a SqlCommandSet throws an ArgumentException.
/// </summary>
[Fact]
public void AppendBadParameterName_Throws()
{
SqlCommandSet cmdSet = new();
using SqlCommand cmd = new("Test");
cmd.CommandType = CommandType.Text;
cmd.Parameters.Add(new SqlParameter("Test1;=", "1"));
ArgumentException ex = Assert.Throws<ArgumentException>(() => cmdSet.Append(cmd));
Assert.Contains("not valid", ex.Message, StringComparison.OrdinalIgnoreCase);
}
/// <summary>
/// Verifies that a SqlParameter containing an array round-trips through a SqlCommandSet correctly.
/// </summary>
[Theory]
[InlineData(new byte[] { 1, 2, 3 })]
[InlineData(new char[] { '1', '2', '3' })]
public void AppendParameterArrayWithSize(object array)
{
SqlCommandSet cmdSet = new();
using SqlCommand cmd = new("Test");
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter("@array", array) { Size = 2 });
cmdSet.Append(cmd);
SqlParameter result = cmdSet.GetParameter(0, 0);
Assert.NotNull(result);
Assert.Equal("@array", result.ParameterName);
Assert.Equal(2, result.Size);
}
/// <summary>
/// Verifies that a SqlParameter containing a scalar value round-trips through a SqlCommandSet correctly.
/// </summary>
[Fact]
public void GetParameter()
{
SqlCommandSet cmdSet = new();
using SqlCommand cmd = new("Test");
cmd.CommandType = CommandType.Text;
cmd.Parameters.Add(new SqlParameter("@text", "value"));
cmdSet.Append(cmd);
SqlParameter result = cmdSet.GetParameter(0, 0);
Assert.NotNull(result);
Assert.Equal("@text", result.ParameterName);
Assert.Equal("value", (string)result.Value);
}
/// <summary>
/// Verifies that SqlCommandSet.GetParameterCount returns the correct number of parameters for a command
/// at the correct index.
/// </summary>
[Fact]
public void GetParameterCount()
{
SqlCommandSet cmdSet = new();
using SqlCommand cmd = new("Test");
cmd.CommandType = CommandType.Text;
cmd.Parameters.Add(new SqlParameter("@abc", "1"));
cmd.Parameters.Add(new SqlParameter("@test", "2"));
cmdSet.Append(cmd);
int index = 0;
int count = cmdSet.GetParameterCount(index);
Assert.Equal(2, count);
}
/// <summary>
/// Verifies that SqlCommandSet.ValidateCommandBehavior throws an ArgumentOutOfRangeException when an invalid CommandBehavior is specified.
/// </summary>
[Fact]
public void InvalidCommandBehaviorValidateCommandBehavior_Throws()
{
SqlCommandSet cmdSet = new();
ArgumentOutOfRangeException ex = Assert.Throws<ArgumentOutOfRangeException>(() => cmdSet.ValidateCommandBehavior("ExecuteNonQuery", (CommandBehavior)64));
Assert.Contains("CommandBehavior", ex.Message, StringComparison.OrdinalIgnoreCase);
}
/// <summary>
/// Verifies that SqlCommandSet.ValidateCommandBehavior throws an ArgumentOutOfRangeException when a valid but unsupported CommandBehavior is specified.
/// </summary>
[Fact]
public void NotSupportedCommandBehaviorValidateCommandBehavior_Throws()
{
SqlCommandSet cmdSet = new();
ArgumentOutOfRangeException ex = Assert.Throws<ArgumentOutOfRangeException>(() => cmdSet.ValidateCommandBehavior("ExecuteNonQuery", CommandBehavior.KeyInfo));
Assert.Contains("not supported", ex.Message, StringComparison.OrdinalIgnoreCase);
}
}

3
src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlTypes/SqlJsonTest.cs

@ -7,10 +7,9 @@
using System;
using System.Data.SqlTypes;
using System.Text.Json;
using Microsoft.Data.SqlTypes;
using Xunit;
namespace Microsoft.Data.SqlClient.UnitTests;
namespace Microsoft.Data.SqlTypes.UnitTests;
public class SqlJsonTest
{

4
src/Microsoft.Data.SqlClient/tests/UnitTests/SqlVectorTest.cs → src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlTypes/SqlVectorTest.cs

@ -4,12 +4,12 @@
// See the LICENSE file in the project root for more information.
using System;
using Microsoft.Data.SqlTypes;
using Microsoft.Data.SqlClient;
using Xunit;
#nullable enable
namespace Microsoft.Data.SqlClient.Tests;
namespace Microsoft.Data.SqlTypes.UnitTests;
public class SqlVectorTest
{
Loading…
Cancel
Save