mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-01-16 01:25:41 -05:00
Adding TestDbResultSet for Better Mocking (#231)
* Replacing the awful and inflexible Dictionary<string, string>[][] with a much better test data set class * Applying all changes * Removing unused RequestParamTests
This commit is contained in:
@@ -19,10 +19,6 @@ using Microsoft.SqlTools.Test.Utility;
|
||||
using Moq;
|
||||
using Moq.Protected;
|
||||
using Xunit;
|
||||
using Microsoft.SqlTools.ServiceLayer.QueryExecution;
|
||||
using Microsoft.SqlTools.ServiceLayer.SqlContext;
|
||||
using Microsoft.SqlTools.ServiceLayer.Test.QueryExecution;
|
||||
using Microsoft.SqlTools.ServiceLayer.Workspace.Contracts;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.Test.Connection
|
||||
{
|
||||
@@ -34,7 +30,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection
|
||||
/// <summary>
|
||||
/// Creates a mock db command that returns a predefined result set
|
||||
/// </summary>
|
||||
public static DbCommand CreateTestCommand(Dictionary<string, string>[][] data)
|
||||
public static DbCommand CreateTestCommand(TestResultSet[] data)
|
||||
{
|
||||
var commandMock = new Mock<DbCommand> { CallBase = true };
|
||||
var commandMockSetup = commandMock.Protected()
|
||||
@@ -48,7 +44,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection
|
||||
/// <summary>
|
||||
/// Creates a mock db connection that returns predefined data when queried for a result set
|
||||
/// </summary>
|
||||
public DbConnection CreateMockDbConnection(Dictionary<string, string>[][] data)
|
||||
public DbConnection CreateMockDbConnection(TestResultSet[] data)
|
||||
{
|
||||
var connectionMock = new Mock<DbConnection> { CallBase = true };
|
||||
connectionMock.Protected()
|
||||
@@ -61,29 +57,26 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection
|
||||
[Fact]
|
||||
public void CanCancelConnectRequest()
|
||||
{
|
||||
var testFile = "file:///my/test/file.sql";
|
||||
const string testFile = "file:///my/test/file.sql";
|
||||
|
||||
// Given a connection that times out and responds to cancellation
|
||||
var mockConnection = new Mock<DbConnection> { CallBase = true };
|
||||
CancellationToken token;
|
||||
bool ready = false;
|
||||
mockConnection.Setup(x => x.OpenAsync(Moq.It.IsAny<CancellationToken>()))
|
||||
mockConnection.Setup(x => x.OpenAsync(It.IsAny<CancellationToken>()))
|
||||
.Callback<CancellationToken>(t =>
|
||||
{
|
||||
// Pass the token to the return handler and signal the main thread to cancel
|
||||
token = t;
|
||||
ready = true;
|
||||
})
|
||||
.Returns(() =>
|
||||
.Returns(() =>
|
||||
{
|
||||
if (TestUtils.WaitFor(() => token.IsCancellationRequested))
|
||||
{
|
||||
throw new OperationCanceledException();
|
||||
}
|
||||
else
|
||||
{
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
return Task.FromResult(true);
|
||||
});
|
||||
|
||||
var mockFactory = new Mock<ISqlConnectionFactory>();
|
||||
@@ -95,15 +88,12 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection
|
||||
|
||||
// Connect the connection asynchronously in a background thread
|
||||
var connectionDetails = TestObjects.GetTestConnectionDetails();
|
||||
var connectTask = Task.Run(async () =>
|
||||
{
|
||||
return await connectionService
|
||||
.Connect(new ConnectParams()
|
||||
{
|
||||
OwnerUri = testFile,
|
||||
Connection = connectionDetails
|
||||
});
|
||||
});
|
||||
var connectTask = Task.Run(async () => await connectionService
|
||||
.Connect(new ConnectParams
|
||||
{
|
||||
OwnerUri = testFile,
|
||||
Connection = connectionDetails
|
||||
}));
|
||||
|
||||
// Wait for the connection to call OpenAsync()
|
||||
Assert.True(TestUtils.WaitFor(() => ready));
|
||||
@@ -128,34 +118,31 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection
|
||||
[Fact]
|
||||
public async Task CanCancelConnectRequestByConnecting()
|
||||
{
|
||||
var testFile = "file:///my/test/file.sql";
|
||||
const string testFile = "file:///my/test/file.sql";
|
||||
|
||||
// Given a connection that times out and responds to cancellation
|
||||
var mockConnection = new Mock<DbConnection> { CallBase = true };
|
||||
CancellationToken token;
|
||||
bool ready = false;
|
||||
mockConnection.Setup(x => x.OpenAsync(Moq.It.IsAny<CancellationToken>()))
|
||||
mockConnection.Setup(x => x.OpenAsync(It.IsAny<CancellationToken>()))
|
||||
.Callback<CancellationToken>(t =>
|
||||
{
|
||||
// Pass the token to the return handler and signal the main thread to cancel
|
||||
token = t;
|
||||
ready = true;
|
||||
})
|
||||
.Returns(() =>
|
||||
.Returns(() =>
|
||||
{
|
||||
if (TestUtils.WaitFor(() => token.IsCancellationRequested))
|
||||
{
|
||||
throw new OperationCanceledException();
|
||||
}
|
||||
else
|
||||
{
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
return Task.FromResult(true);
|
||||
});
|
||||
|
||||
// Given a second connection that succeeds
|
||||
var mockConnection2 = new Mock<DbConnection> { CallBase = true };
|
||||
mockConnection2.Setup(x => x.OpenAsync(Moq.It.IsAny<CancellationToken>()))
|
||||
mockConnection2.Setup(x => x.OpenAsync(It.IsAny<CancellationToken>()))
|
||||
.Returns(() => Task.Run(() => {}));
|
||||
|
||||
var mockFactory = new Mock<ISqlConnectionFactory>();
|
||||
@@ -168,15 +155,12 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection
|
||||
|
||||
// Connect the first connection asynchronously in a background thread
|
||||
var connectionDetails = TestObjects.GetTestConnectionDetails();
|
||||
var connectTask = Task.Run(async () =>
|
||||
{
|
||||
return await connectionService
|
||||
.Connect(new ConnectParams()
|
||||
{
|
||||
OwnerUri = testFile,
|
||||
Connection = connectionDetails
|
||||
});
|
||||
});
|
||||
var connectTask = Task.Run(async () => await connectionService
|
||||
.Connect(new ConnectParams()
|
||||
{
|
||||
OwnerUri = testFile,
|
||||
Connection = connectionDetails
|
||||
}));
|
||||
|
||||
// Wait for the connection to call OpenAsync()
|
||||
Assert.True(TestUtils.WaitFor(() => ready));
|
||||
@@ -202,13 +186,13 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection
|
||||
[Fact]
|
||||
public void CanCancelConnectRequestByDisconnecting()
|
||||
{
|
||||
var testFile = "file:///my/test/file.sql";
|
||||
const string testFile = "file:///my/test/file.sql";
|
||||
|
||||
// Given a connection that times out and responds to cancellation
|
||||
var mockConnection = new Mock<DbConnection> { CallBase = true };
|
||||
CancellationToken token;
|
||||
bool ready = false;
|
||||
mockConnection.Setup(x => x.OpenAsync(Moq.It.IsAny<CancellationToken>()))
|
||||
mockConnection.Setup(x => x.OpenAsync(It.IsAny<CancellationToken>()))
|
||||
.Callback<CancellationToken>(t =>
|
||||
{
|
||||
// Pass the token to the return handler and signal the main thread to cancel
|
||||
@@ -221,10 +205,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection
|
||||
{
|
||||
throw new OperationCanceledException();
|
||||
}
|
||||
else
|
||||
{
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
return Task.FromResult(true);
|
||||
});
|
||||
|
||||
var mockFactory = new Mock<ISqlConnectionFactory>();
|
||||
@@ -236,22 +217,19 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection
|
||||
|
||||
// Connect the first connection asynchronously in a background thread
|
||||
var connectionDetails = TestObjects.GetTestConnectionDetails();
|
||||
var connectTask = Task.Run(async () =>
|
||||
{
|
||||
return await connectionService
|
||||
.Connect(new ConnectParams()
|
||||
{
|
||||
OwnerUri = testFile,
|
||||
Connection = connectionDetails
|
||||
});
|
||||
});
|
||||
var connectTask = Task.Run(async () => await connectionService
|
||||
.Connect(new ConnectParams
|
||||
{
|
||||
OwnerUri = testFile,
|
||||
Connection = connectionDetails
|
||||
}));
|
||||
|
||||
// Wait for the connection to call OpenAsync()
|
||||
Assert.True(TestUtils.WaitFor(() => ready));
|
||||
|
||||
// Send a cancellation by trying to disconnect
|
||||
var disconnectResult = connectionService
|
||||
.Disconnect(new DisconnectParams()
|
||||
.Disconnect(new DisconnectParams
|
||||
{
|
||||
OwnerUri = testFile
|
||||
});
|
||||
@@ -382,16 +360,19 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection
|
||||
public async Task ConnectingWithInvalidCredentialsYieldsErrorMessage()
|
||||
{
|
||||
var testConnectionDetails = TestObjects.GetTestConnectionDetails();
|
||||
var invalidConnectionDetails = new ConnectionDetails();
|
||||
invalidConnectionDetails.ServerName = testConnectionDetails.ServerName;
|
||||
invalidConnectionDetails.DatabaseName = testConnectionDetails.DatabaseName;
|
||||
invalidConnectionDetails.UserName = "invalidUsername"; // triggers exception when opening mock connection
|
||||
invalidConnectionDetails.Password = "invalidPassword";
|
||||
var invalidConnectionDetails = new ConnectionDetails
|
||||
{
|
||||
ServerName = testConnectionDetails.ServerName,
|
||||
DatabaseName = testConnectionDetails.DatabaseName,
|
||||
UserName = "invalidUsername",
|
||||
Password = "invalidPassword"
|
||||
};
|
||||
// triggers exception when opening mock connection
|
||||
|
||||
// Connect to test db with invalid credentials
|
||||
var connectionResult = await
|
||||
TestObjects.GetTestConnectionService()
|
||||
.Connect(new ConnectParams()
|
||||
.Connect(new ConnectParams
|
||||
{
|
||||
OwnerUri = "file://my/sample/file.sql",
|
||||
Connection = invalidConnectionDetails
|
||||
@@ -563,7 +544,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection
|
||||
connectionService.ServiceHost = serviceHostMock.Object;
|
||||
|
||||
// Set up an initial connection
|
||||
string ownerUri = "file://my/sample/file.sql";
|
||||
const string ownerUri = "file://my/sample/file.sql";
|
||||
var connectionResult = await
|
||||
connectionService
|
||||
.Connect(new ConnectParams()
|
||||
@@ -578,11 +559,11 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection
|
||||
ConnectionInfo info;
|
||||
Assert.True(connectionService.TryFindConnection(ownerUri, out info));
|
||||
|
||||
// Tell the connection manager that the database change ocurred
|
||||
// Tell the connection manager that the database change occurred
|
||||
connectionService.ChangeConnectionDatabaseContext(ownerUri, "myOtherDb");
|
||||
|
||||
// Verify that the connection changed event was fired
|
||||
serviceHostMock.Verify(x => x.SendEvent<ConnectionChangedParams>(ConnectionChangedNotification.Type, It.IsAny<ConnectionChangedParams>()), Times.Once());
|
||||
serviceHostMock.Verify(x => x.SendEvent(ConnectionChangedNotification.Type, It.IsAny<ConnectionChangedParams>()), Times.Once());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -606,7 +587,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verify that we can disconnect from an active connection succesfully
|
||||
/// Verify that we can disconnect from an active connection successfully
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public async Task DisconnectFromDatabaseTest()
|
||||
@@ -758,14 +739,16 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection
|
||||
public async Task ListDatabasesOnServerForCurrentConnectionReturnsDatabaseNames()
|
||||
{
|
||||
// Result set for the query of database names
|
||||
Dictionary<string, string>[] data =
|
||||
TestDbColumn[] cols = {new TestDbColumn("name")};
|
||||
object[][] rows =
|
||||
{
|
||||
new Dictionary<string, string> { {"name", "master" } },
|
||||
new Dictionary<string, string> { {"name", "model" } },
|
||||
new Dictionary<string, string> { {"name", "msdb" } },
|
||||
new Dictionary<string, string> { {"name", "tempdb" } },
|
||||
new Dictionary<string, string> { {"name", "mydatabase" } },
|
||||
new object[] {"master"},
|
||||
new object[] {"model"},
|
||||
new object[] {"msdb"},
|
||||
new object[] {"tempdb"},
|
||||
new object[] {"mydatabase"}
|
||||
};
|
||||
TestResultSet data = new TestResultSet(cols, rows);
|
||||
|
||||
// Setup mock connection factory to inject query results
|
||||
var mockFactory = new Mock<ISqlConnectionFactory>();
|
||||
@@ -787,8 +770,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection
|
||||
Assert.NotEmpty(connectionResult.ConnectionId);
|
||||
|
||||
// list databases for the connection
|
||||
ListDatabasesParams parameters = new ListDatabasesParams();
|
||||
parameters.OwnerUri = ownerUri;
|
||||
ListDatabasesParams parameters = new ListDatabasesParams {OwnerUri = ownerUri};
|
||||
var listDatabasesResult = connectionService.ListDatabases(parameters);
|
||||
string[] databaseNames = listDatabasesResult.DatabaseNames;
|
||||
|
||||
@@ -818,7 +800,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection
|
||||
);
|
||||
|
||||
// connect to a database instance
|
||||
var connectionResult = await connectionService.Connect(TestObjects.GetTestConnectionParams());
|
||||
await connectionService.Connect(TestObjects.GetTestConnectionParams());
|
||||
|
||||
// verify that a valid connection id was returned
|
||||
Assert.True(callbackInvoked);
|
||||
@@ -869,7 +851,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection
|
||||
|
||||
// verify that a valid connection id was returned
|
||||
Assert.NotNull(connectionResult.ConnectionId);
|
||||
Assert.NotEqual(String.Empty, connectionResult.ConnectionId);
|
||||
Assert.NotEqual(string.Empty, connectionResult.ConnectionId);
|
||||
Assert.NotNull(new Guid(connectionResult.ConnectionId));
|
||||
|
||||
// verify that the (URI -> connection) mapping was created
|
||||
@@ -885,16 +867,18 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection
|
||||
/// and remove the code block specific to Linux/OSX.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void TestThatLinuxAndOSXSqlExceptionHasNoErrorCode()
|
||||
public void TestThatLinuxAndOsxSqlExceptionHasNoErrorCode()
|
||||
{
|
||||
TestUtils.RunIfLinuxOrOSX(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder();
|
||||
builder.DataSource = "bad-server-name";
|
||||
builder.UserID = "sa";
|
||||
builder.Password = "bad password";
|
||||
SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder
|
||||
{
|
||||
DataSource = "bad-server-name",
|
||||
UserID = "sa",
|
||||
Password = "bad password"
|
||||
};
|
||||
|
||||
SqlConnection connection = new SqlConnection(builder.ConnectionString);
|
||||
connection.Open(); // This should fail
|
||||
@@ -907,7 +891,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection
|
||||
});
|
||||
}
|
||||
|
||||
// <summary>
|
||||
/// <summary>
|
||||
/// Test that cancel connection with a null connection parameter
|
||||
/// </summary>
|
||||
[Fact]
|
||||
@@ -917,7 +901,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection
|
||||
Assert.False(service.CancelConnect(null));
|
||||
}
|
||||
|
||||
// <summary>
|
||||
/// <summary>
|
||||
/// Test that cancel connection with a null connection parameter
|
||||
/// </summary>
|
||||
[Fact]
|
||||
@@ -941,7 +925,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection
|
||||
|
||||
/// <summary>
|
||||
/// Test that the connection summary comparer creates a hash code correctly
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
[Theory]
|
||||
[InlineData(true, null, null ,null)]
|
||||
[InlineData(false, null, null, null)]
|
||||
@@ -985,9 +969,11 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection
|
||||
public void ConnectParamsAreInvalidIfConnectionIsNull()
|
||||
{
|
||||
// Given connection parameters where the connection property is null
|
||||
ConnectParams parameters = new ConnectParams();
|
||||
parameters.OwnerUri = "my/sql/file.sql";
|
||||
parameters.Connection = null;
|
||||
ConnectParams parameters = new ConnectParams
|
||||
{
|
||||
OwnerUri = "my/sql/file.sql",
|
||||
Connection = null
|
||||
};
|
||||
|
||||
string errorMessage;
|
||||
|
||||
@@ -1044,11 +1030,11 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection
|
||||
await service.Connect(connectParamsDifferent);
|
||||
Assert.Equal(2, ownerToConnectionMap.Count);
|
||||
|
||||
// If we disconenct with the unique URI, there should be 1 connection
|
||||
// If we disconnect with the unique URI, there should be 1 connection
|
||||
service.Disconnect(disconnectParamsDifferent);
|
||||
Assert.Equal(1, ownerToConnectionMap.Count);
|
||||
|
||||
// If we disconenct with the duplicate URI, there should be 0 connections
|
||||
// If we disconnect with the duplicate URI, there should be 0 connections
|
||||
service.Disconnect(disconnectParamsSame);
|
||||
Assert.Equal(0, ownerToConnectionMap.Count);
|
||||
}
|
||||
@@ -1138,7 +1124,6 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Connection
|
||||
|
||||
// If I connect a Default and a Query connection
|
||||
var service = TestObjects.GetTestConnectionService();
|
||||
Dictionary<string, ConnectionInfo> ownerToConnectionMap = service.OwnerToConnectionMap;
|
||||
await service.Connect(connectParamsDefault);
|
||||
await service.Connect(connectParamsQuery);
|
||||
ConnectionInfo connectionInfo = service.OwnerToConnectionMap[connectParamsDefault.OwnerUri];
|
||||
|
||||
Reference in New Issue
Block a user