diff --git a/src/Microsoft.SqlTools.ServiceLayer/LanguageServices/ConnectedBindingQueue.cs b/src/Microsoft.SqlTools.ServiceLayer/LanguageServices/ConnectedBindingQueue.cs index 1c4fc414..85b9d33c 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/LanguageServices/ConnectedBindingQueue.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/LanguageServices/ConnectedBindingQueue.cs @@ -32,6 +32,17 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices int? waitForLockTimeout = null); } + public class SqlConnectionOpener + { + /// + /// Virtual method used to support mocking and testing + /// + public virtual SqlConnection OpenSqlConnection(ConnectionInfo connInfo, string featureName) + { + return ConnectionService.OpenSqlConnection(connInfo, featureName); + } + } + /// /// ConnectedBindingQueue class for processing online binding requests /// @@ -46,6 +57,7 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices /// it's much cheaper to not construct these objects if not needed /// private bool needsMetadata; + private SqlConnectionOpener connectionOpener; /// /// Gets the current settings @@ -63,6 +75,13 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices public ConnectedBindingQueue(bool needsMetadata) { this.needsMetadata = needsMetadata; + this.connectionOpener = new SqlConnectionOpener(); + } + + // For testing purposes only + internal void SetConnectionOpener(SqlConnectionOpener opener) + { + this.connectionOpener = opener; } /// @@ -179,7 +198,7 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices try { bindingContext.BindingLock.Reset(); - SqlConnection sqlConn = ConnectionService.OpenSqlConnection(connInfo, featureName); + SqlConnection sqlConn = connectionOpener.OpenSqlConnection(connInfo, featureName); // populate the binding context to work with the SMO metadata provider bindingContext.ServerConnection = new ServerConnection(sqlConn); diff --git a/test/Microsoft.SqlTools.ServiceLayer.UnitTests/ObjectExplorer/ObjectExplorerServiceTests.cs b/test/Microsoft.SqlTools.ServiceLayer.UnitTests/ObjectExplorer/ObjectExplorerServiceTests.cs index 52f4ac07..1974df80 100644 --- a/test/Microsoft.SqlTools.ServiceLayer.UnitTests/ObjectExplorer/ObjectExplorerServiceTests.cs +++ b/test/Microsoft.SqlTools.ServiceLayer.UnitTests/ObjectExplorer/ObjectExplorerServiceTests.cs @@ -40,6 +40,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.ObjectExplorer ConnectionInfo connectionInfo = new ConnectionInfo(null, null, details); ConnectedBindingQueue connectedBindingQueue; + Mock mockConnectionOpener; public ObjectExplorerServiceTests() { connectionServiceMock = new Mock(); @@ -51,6 +52,8 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.ObjectExplorer connectedBindingContext.ServerConnection = new ServerConnection(new SqlConnection(fakeConnectionString)); connectedBindingQueue = new ConnectedBindingQueue(false); connectedBindingQueue.BindingContextMap.Add($"{details.ServerName}_{details.DatabaseName}_{details.UserName}_NULL", connectedBindingContext); + mockConnectionOpener = new Mock(); + connectedBindingQueue.SetConnectionOpener(mockConnectionOpener.Object); service.ConnectedBindingQueue = connectedBindingQueue; } @@ -400,9 +403,11 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.ObjectExplorer private async Task CreateSessionRequestAndVerifyServerNodeHelper(ConnectionDetails details) { serviceHostMock.AddEventHandling(ConnectionCompleteNotification.Type, null); - //SessionCreatedParameters sessionResult - + // Stub out the connection to avoid a 30second timeout while attempting to connect. + // The tests don't need any connection context anyhow so this doesn't impact the scenario + mockConnectionOpener.Setup(b => b.OpenSqlConnection(It.IsAny(), It.IsAny())) + .Throws(); connectionServiceMock.Setup(c => c.Connect(It.IsAny())) .Returns((ConnectParams connectParams) => Task.FromResult(GetCompleteParamsForConnection(connectParams.OwnerUri, details))); ConnectionInfo connectionInfo = new ConnectionInfo(null, null, details);