This is an automated email from the ASF dual-hosted git repository.

florianhockmann pushed a commit to branch TINKERPOP-2984-replace-moq
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git

commit be1dea6776ac7152f4266d162fccfa9d88fd5505
Author: Florian Hockmann <[email protected]>
AuthorDate: Wed Aug 16 14:59:38 2023 +0200

    TINKERPOP-2984 Replace Moq with NSubstitute WIP
    
    Still missing are the logging tests. Looks like NSubstitute still lacks
    some functionality for this, but it should be supported soon:
    https://github.com/nsubstitute/NSubstitute/issues/634
---
 .../Driver/ConnectionPoolTests.cs                  | 238 ++++++++++-----------
 .../Gremlin.Net.UnitTest/Driver/ConnectionTests.cs | 205 +++++++++---------
 .../Driver/DriverRemoteConnectionTests.cs          |   8 +-
 .../Gremlin.Net.UnitTest.csproj                    |   1 +
 .../Process/Remote/RemoteTransactionTests.cs       |   6 +-
 .../Structure/IO/GraphSON/GraphSONReaderTests.cs   |   8 +-
 .../Structure/IO/GraphSON/GraphSONWriterTests.cs   |  24 ++-
 7 files changed, 242 insertions(+), 248 deletions(-)

diff --git 
a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Driver/ConnectionPoolTests.cs 
b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Driver/ConnectionPoolTests.cs
index 0fbc02aadb..078440118c 100644
--- a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Driver/ConnectionPoolTests.cs
+++ b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Driver/ConnectionPoolTests.cs
@@ -28,7 +28,9 @@ using System.Threading.Tasks;
 using Gremlin.Net.Driver;
 using Gremlin.Net.Driver.Exceptions;
 using Microsoft.Extensions.Logging.Abstractions;
-using Moq;
+using NSubstitute;
+using NSubstitute.ExceptionExtensions;
+using NSubstitute.Extensions;
 using Xunit;
 
 namespace Gremlin.Net.UnitTest.Driver
@@ -41,24 +43,24 @@ namespace Gremlin.Net.UnitTest.Driver
         [InlineData(10)]
         public void ShouldEstablishConfiguredNrConnections(int poolSize)
         {
-            var mockedConnectionFactory = new Mock<IConnectionFactory>();
-            var mockedConnection = new Mock<IConnection>();
-            mockedConnectionFactory.Setup(m => 
m.CreateConnection()).Returns(mockedConnection.Object);
-            var pool = CreateConnectionPool(mockedConnectionFactory.Object, 
poolSize);
+            var mockedConnectionFactory = Substitute.For<IConnectionFactory>();
+            var mockedConnection = Substitute.For<IConnection>();
+            
mockedConnectionFactory.CreateConnection().Returns(mockedConnection);
+            var pool = CreateConnectionPool(mockedConnectionFactory, poolSize);
             
             Assert.Equal(poolSize, pool.NrConnections);
-            mockedConnectionFactory.Verify(m => m.CreateConnection(), 
Times.Exactly(poolSize));
-            mockedConnection.Verify(m => 
m.ConnectAsync(It.IsAny<CancellationToken>()), Times.Exactly(poolSize));
+            mockedConnectionFactory.Received(poolSize).CreateConnection();
+            
mockedConnection.Received(poolSize).ConnectAsync(Arg.Any<CancellationToken>());
         }
 
         [Fact]
         public void GetAvailableConnectionShouldReturnFirstOpenConnection()
         {
-            var fakeConnectionFactory = new Mock<IConnectionFactory>();
+            var fakeConnectionFactory = Substitute.For<IConnectionFactory>();
             var openConnectionToReturn = OpenConnection;
-            fakeConnectionFactory.SetupSequence(m => 
m.CreateConnection()).Returns(ClosedConnection)
-                .Returns(ClosedConnection).Returns(openConnectionToReturn);
-            var pool = CreateConnectionPool(fakeConnectionFactory.Object, 3);
+            fakeConnectionFactory.CreateConnection().Returns(_ => 
ClosedConnection, _ => ClosedConnection,
+                _ => openConnectionToReturn);
+            var pool = CreateConnectionPool(fakeConnectionFactory, 3);
 
             var returnedConnection = pool.GetAvailableConnection();
 
@@ -68,9 +70,9 @@ namespace Gremlin.Net.UnitTest.Driver
         [Fact]
         public void 
GetAvailableConnectionShouldThrowIfAllConnectionsAreClosed()
         {
-            var fakeConnectionFactory = new Mock<IConnectionFactory>();
-            fakeConnectionFactory.Setup(m => 
m.CreateConnection()).Returns(ClosedConnection);
-            var pool = CreateConnectionPool(fakeConnectionFactory.Object);
+            var fakeConnectionFactory = Substitute.For<IConnectionFactory>();
+            fakeConnectionFactory.CreateConnection().Returns(_ => 
ClosedConnection);
+            var pool = CreateConnectionPool(fakeConnectionFactory);
 
             Assert.Throws<ServerUnavailableException>(() => 
pool.GetAvailableConnection());
         }
@@ -78,11 +80,11 @@ namespace Gremlin.Net.UnitTest.Driver
         [Fact]
         public void GetAvailableConnectionShouldEmptyPoolIfServerUnavailable()
         {
-            var fakeConnectionFactory = new Mock<IConnectionFactory>();
-            fakeConnectionFactory.SetupSequence(m => 
m.CreateConnection()).Returns(ClosedConnection)
-                .Returns(ClosedConnection).Returns(ClosedConnection);
-            var pool = CreateConnectionPool(fakeConnectionFactory.Object, 3);
-            fakeConnectionFactory.Setup(m => 
m.CreateConnection()).Returns(CannotConnectConnection);
+            var fakeConnectionFactory = Substitute.For<IConnectionFactory>();
+            fakeConnectionFactory.CreateConnection()
+                .Returns(_ => ClosedConnection, _ => ClosedConnection, _ => 
ClosedConnection);
+            var pool = CreateConnectionPool(fakeConnectionFactory, 3);
+            fakeConnectionFactory.Configure().CreateConnection().Returns(_ => 
CannotConnectConnection);
 
             Assert.Throws<ServerUnavailableException>(() => 
pool.GetAvailableConnection());
                 
@@ -92,15 +94,15 @@ namespace Gremlin.Net.UnitTest.Driver
         [Fact]
         public void GetAvailableConnectionShouldEventuallyRefillPoolIfEmpty()
         {
-            var fakeConnectionFactory = new Mock<IConnectionFactory>();
-            fakeConnectionFactory.SetupSequence(m => 
m.CreateConnection()).Returns(ClosedConnection)
-                .Returns(ClosedConnection).Returns(ClosedConnection);
-            var pool = CreateConnectionPool(fakeConnectionFactory.Object, 3);
-            fakeConnectionFactory.Setup(m => 
m.CreateConnection()).Returns(CannotConnectConnection);
+            var fakeConnectionFactory = Substitute.For<IConnectionFactory>();
+            fakeConnectionFactory.CreateConnection()
+                .Returns(_ => ClosedConnection, _ => ClosedConnection, _ => 
ClosedConnection);
+            var pool = CreateConnectionPool(fakeConnectionFactory, 3);
+            fakeConnectionFactory.Configure().CreateConnection().Returns(_ => 
CannotConnectConnection);
             Assert.Throws<ServerUnavailableException>(() => 
pool.GetAvailableConnection());
             // Pool is now empty
-            Assert.Equal(0, pool.NrConnections); 
-            fakeConnectionFactory.Setup(m => 
m.CreateConnection()).Returns(OpenConnection);
+            Assert.Equal(0, pool.NrConnections);
+            fakeConnectionFactory.Configure().CreateConnection().Returns(_ => 
OpenConnection);
             
             pool.GetAvailableConnection();
             
@@ -110,19 +112,17 @@ namespace Gremlin.Net.UnitTest.Driver
         [Fact]
         public void 
GetAvailableConnectionsShouldEventuallyFillUpPoolIfNotFull()
         {
-            var fakeConnectionFactory = new Mock<IConnectionFactory>();
-            fakeConnectionFactory.SetupSequence(m => m.CreateConnection())
-                .Returns(ClosedConnection)
-                .Returns(ClosedConnection)
-                .Returns(OpenConnection);
-            var pool = CreateConnectionPool(fakeConnectionFactory.Object, 3);
-            fakeConnectionFactory.Setup(m => 
m.CreateConnection()).Returns(CannotConnectConnection);
+            var fakeConnectionFactory = Substitute.For<IConnectionFactory>();
+            fakeConnectionFactory.CreateConnection()
+                .Returns(_ => ClosedConnection, _ => ClosedConnection, _ => 
OpenConnection);
+            var pool = CreateConnectionPool(fakeConnectionFactory, 3);
+            fakeConnectionFactory.Configure().CreateConnection().Returns(_ => 
CannotConnectConnection);
             pool.GetAvailableConnection();
             pool.GetAvailableConnection();
             // Pool is now just partially filled
             Assert.Equal(1, pool.NrConnections); 
             
-            fakeConnectionFactory.Setup(m => 
m.CreateConnection()).Returns(OpenConnection);
+            fakeConnectionFactory.Configure().CreateConnection().Returns(_ => 
OpenConnection);
             pool.GetAvailableConnection();
             
             AssertNrOpenConnections(pool, 3);
@@ -131,11 +131,11 @@ namespace Gremlin.Net.UnitTest.Driver
         [Fact]
         public void GetAvailableConnectionShouldReplaceClosedConnections()
         {
-            var fakeConnectionFactory = new Mock<IConnectionFactory>();
-            fakeConnectionFactory.SetupSequence(m => 
m.CreateConnection()).Returns(ClosedConnection)
-                .Returns(ClosedConnection).Returns(OpenConnection);
-            var pool = CreateConnectionPool(fakeConnectionFactory.Object, 3);
-            fakeConnectionFactory.Setup(m => 
m.CreateConnection()).Returns(OpenConnection);
+            var fakeConnectionFactory = Substitute.For<IConnectionFactory>();
+            fakeConnectionFactory.CreateConnection()
+                .Returns(_ => ClosedConnection, _ => ClosedConnection, _ => 
OpenConnection);
+            var pool = CreateConnectionPool(fakeConnectionFactory, 3);
+            fakeConnectionFactory.Configure().CreateConnection().Returns(_ => 
OpenConnection);
             var nrCreatedConnections = pool.NrConnections;
             
             pool.GetAvailableConnection();
@@ -158,11 +158,11 @@ namespace Gremlin.Net.UnitTest.Driver
         [Fact]
         public async Task 
ShouldNotCreateMoreConnectionsThanConfiguredForParallelRequests()
         {
-            var mockedConnectionFactory = new Mock<IConnectionFactory>();
-            mockedConnectionFactory.SetupSequence(m => 
m.CreateConnection()).Returns(ClosedConnection)
-                .Returns(ClosedConnection).Returns(OpenConnection);
-            var pool = CreateConnectionPool(mockedConnectionFactory.Object, 3);
-            mockedConnectionFactory.Setup(m => 
m.CreateConnection()).Returns(OpenConnection);
+            var mockedConnectionFactory = Substitute.For<IConnectionFactory>();
+            mockedConnectionFactory.CreateConnection()
+                .Returns(_ => ClosedConnection, _ => ClosedConnection, _ => 
OpenConnection);
+            var pool = CreateConnectionPool(mockedConnectionFactory, 3);
+            mockedConnectionFactory.Configure().CreateConnection().Returns(_ 
=> OpenConnection);
             var nrCreatedConnections = pool.NrConnections;
             var getConnectionTasks = new List<Task<IConnection>>();
 
@@ -179,14 +179,14 @@ namespace Gremlin.Net.UnitTest.Driver
         [Fact]
         public async Task ShouldReplaceConnectionClosedDuringSubmit()
         {
-            var mockedConnectionFactory = new Mock<IConnectionFactory>();
-            var fakedConnection = new Mock<IConnection>();
-            fakedConnection.Setup(f => f.IsOpen).Returns(true);
-            mockedConnectionFactory.Setup(m => 
m.CreateConnection()).Returns(fakedConnection.Object);
-            var pool = CreateConnectionPool(mockedConnectionFactory.Object, 1);
+            var mockedConnectionFactory = Substitute.For<IConnectionFactory>();
+            var fakedConnection = Substitute.For<IConnection>();
+            fakedConnection.IsOpen.Returns(true);
+            
mockedConnectionFactory.CreateConnection().Returns(fakedConnection);
+            var pool = CreateConnectionPool(mockedConnectionFactory, 1);
             var returnedConnection = pool.GetAvailableConnection();
-            fakedConnection.Setup(f => f.IsOpen).Returns(false);
-            mockedConnectionFactory.Setup(m => 
m.CreateConnection()).Returns(OpenConnection);
+            fakedConnection.IsOpen.Returns(false);
+            mockedConnectionFactory.CreateConnection().Returns(_ => 
OpenConnection);
 
             await returnedConnection.SubmitAsync<bool>(null, 
CancellationToken.None);
             returnedConnection.Dispose();
@@ -198,10 +198,10 @@ namespace Gremlin.Net.UnitTest.Driver
         [Fact]
         public void ShouldWaitForHostToBecomeAvailable()
         {
-            var fakeConnectionFactory = new Mock<IConnectionFactory>();
-            fakeConnectionFactory.Setup(m => 
m.CreateConnection()).Returns(ClosedConnection);
-            var pool = CreateConnectionPool(fakeConnectionFactory.Object, 1);
-            fakeConnectionFactory.Setup(m => 
m.CreateConnection()).Returns(OpenConnection);
+            var fakeConnectionFactory = Substitute.For<IConnectionFactory>();
+            fakeConnectionFactory.CreateConnection().Returns(_ => 
ClosedConnection);
+            var pool = CreateConnectionPool(fakeConnectionFactory, 1);
+            fakeConnectionFactory.Configure().CreateConnection().Returns(_ => 
OpenConnection);
             var nrCreatedConnections = pool.NrConnections;
             
             var connection = pool.GetAvailableConnection();
@@ -216,13 +216,13 @@ namespace Gremlin.Net.UnitTest.Driver
         [InlineData(2)]
         public void 
ShouldPerformConfiguredNrReconnectionAttemptsForUnavailableServer(int 
nrAttempts)
         {
-            var mockedConnectionFactory = new Mock<IConnectionFactory>();
-            mockedConnectionFactory.Setup(m => 
m.CreateConnection()).Returns(ClosedConnection);
-            var pool = CreateConnectionPool(mockedConnectionFactory.Object, 1, 
nrAttempts);
+            var mockedConnectionFactory = Substitute.For<IConnectionFactory>();
+            mockedConnectionFactory.CreateConnection().Returns(_ => 
ClosedConnection);
+            var pool = CreateConnectionPool(mockedConnectionFactory, 1, 
nrAttempts);
 
             Assert.ThrowsAny<Exception>(() => pool.GetAvailableConnection());
 
-            mockedConnectionFactory.Verify(m => m.CreateConnection(), 
Times.Exactly(nrAttempts + 2));
+            mockedConnectionFactory.Received(nrAttempts + 
2).CreateConnection();
             // 2 additional calls are expected: 1 for the initial creation of 
the pool and 1 when the connection should
             // be returned and none is open for the first attempt (before any 
retries)
         }
@@ -230,29 +230,29 @@ namespace Gremlin.Net.UnitTest.Driver
         [Fact]
         public void ShouldThrowAfterWaitingTooLongForUnavailableServer()
         {
-            var fakeConnectionFactory = new Mock<IConnectionFactory>();
-            fakeConnectionFactory.Setup(m => 
m.CreateConnection()).Returns(ClosedConnection);
-            var pool = CreateConnectionPool(fakeConnectionFactory.Object, 1);
+            var fakeConnectionFactory = Substitute.For<IConnectionFactory>();
+            fakeConnectionFactory.CreateConnection().Returns(_ => 
ClosedConnection);
+            var pool = CreateConnectionPool(fakeConnectionFactory, 1);
             
             Assert.Throws<ServerUnavailableException>(() => 
pool.GetAvailableConnection());
         }
-
+        
         [Fact]
         public async Task 
ShouldNotLeakConnectionsIfDisposeIsCalledWhilePoolIsPopulating()
         {
-            var fakeConnectionFactory = new Mock<IConnectionFactory>();
-            fakeConnectionFactory.Setup(m => 
m.CreateConnection()).Returns(ClosedConnection);
-            var pool = CreateConnectionPool(fakeConnectionFactory.Object, 1);
-            var mockedConnectionToBeDisposed = new Mock<IConnection>();
+            var fakeConnectionFactory = Substitute.For<IConnectionFactory>();
+            fakeConnectionFactory.CreateConnection().Returns(_ => 
ClosedConnection);
+            var pool = CreateConnectionPool(fakeConnectionFactory, 1);
+            var mockedConnectionToBeDisposed = Substitute.For<IConnection>();
             var poolWasDisposedSignal = new SemaphoreSlim(0, 1);
-            mockedConnectionToBeDisposed.Setup(m => 
m.ConnectAsync(It.IsAny<CancellationToken>()))
-                .Returns((CancellationToken _) => 
poolWasDisposedSignal.WaitAsync(CancellationToken.None));
+            
mockedConnectionToBeDisposed.ConnectAsync(Arg.Any<CancellationToken>())
+                .Returns(x => 
poolWasDisposedSignal.WaitAsync(CancellationToken.None));
             var connectionWasSuccessfullyDisposed = new SemaphoreSlim(0, 1);
-            mockedConnectionToBeDisposed.Setup(m => m.Dispose())
-                .Callback(() => connectionWasSuccessfullyDisposed.Release());
+            mockedConnectionToBeDisposed.When(x => x.Dispose())
+                .Do(_ => connectionWasSuccessfullyDisposed.Release());
             // We don't use the `CancellationToken` here as the connection 
should also be disposed if it did not
             //  react on the cancellation. This can happen if the task is 
cancelled just before `ConnectAsync` returns.
-            fakeConnectionFactory.Setup(m => 
m.CreateConnection()).Returns(mockedConnectionToBeDisposed.Object);
+            
fakeConnectionFactory.Configure().CreateConnection().Returns(mockedConnectionToBeDisposed);
             try
             {
                 pool.GetAvailableConnection();
@@ -267,23 +267,23 @@ namespace Gremlin.Net.UnitTest.Driver
             
             await 
connectionWasSuccessfullyDisposed.WaitAsync(TimeSpan.FromSeconds(2));
             Assert.Equal(0, pool.NrConnections);
-            mockedConnectionToBeDisposed.Verify(m => 
m.ConnectAsync(It.IsAny<CancellationToken>()), Times.Once);
-            mockedConnectionToBeDisposed.Verify(m => m.Dispose(), Times.Once);
+            await 
mockedConnectionToBeDisposed.Received(1).ConnectAsync(Arg.Any<CancellationToken>());
+            mockedConnectionToBeDisposed.Received(1).Dispose();
         }
-
+        
         [Fact]
         public async Task DisposeShouldCancelConnectionEstablishment()
         {
-            var fakeConnectionFactory = new Mock<IConnectionFactory>();
-            fakeConnectionFactory.Setup(m => 
m.CreateConnection()).Returns(ClosedConnection);
-            var pool = CreateConnectionPool(fakeConnectionFactory.Object, 1, 
0);
-            var mockedConnectionToBeDisposed = new Mock<IConnection>();
-            mockedConnectionToBeDisposed.Setup(f => 
f.ConnectAsync(It.IsAny<CancellationToken>()))
-                .Returns((CancellationToken ct) => Task.Delay(-1, ct));
+            var fakeConnectionFactory = Substitute.For<IConnectionFactory>();
+            fakeConnectionFactory.CreateConnection().Returns(_ => 
ClosedConnection);
+            var pool = CreateConnectionPool(fakeConnectionFactory, 1, 0);
+            var mockedConnectionToBeDisposed = Substitute.For<IConnection>();
+            
mockedConnectionToBeDisposed.ConnectAsync(Arg.Any<CancellationToken>())
+                .Returns(x => Task.Delay(-1, (CancellationToken)x[0]));
             var connectionWasSuccessfullyDisposed = new SemaphoreSlim(0, 1);
-            mockedConnectionToBeDisposed.Setup(m => m.Dispose())
-                .Callback(() => connectionWasSuccessfullyDisposed.Release());
-            fakeConnectionFactory.Setup(m => 
m.CreateConnection()).Returns(mockedConnectionToBeDisposed.Object);
+            mockedConnectionToBeDisposed.When(x => x.Dispose())
+                .Do(_ => connectionWasSuccessfullyDisposed.Release());
+            
fakeConnectionFactory.Configure().CreateConnection().Returns(mockedConnectionToBeDisposed);
             try
             {
                 pool.GetAvailableConnection();
@@ -294,11 +294,11 @@ namespace Gremlin.Net.UnitTest.Driver
             }
             
             pool.Dispose();
-
+        
             await 
connectionWasSuccessfullyDisposed.WaitAsync(TimeSpan.FromSeconds(2));
             Assert.Equal(0, pool.NrConnections);
-            mockedConnectionToBeDisposed.Verify(m => 
m.ConnectAsync(It.IsAny<CancellationToken>()));
-            mockedConnectionToBeDisposed.Verify(m => m.Dispose(), Times.Once);
+            await 
mockedConnectionToBeDisposed.Received(1).ConnectAsync(Arg.Any<CancellationToken>());
+            mockedConnectionToBeDisposed.Received(1).Dispose();
         }
         
         [Fact]
@@ -309,20 +309,19 @@ namespace Gremlin.Net.UnitTest.Driver
             //  exception.
             
             // First create a pool with only closed connections that we can 
then let the pool replace:
-            var fakeConnectionFactory = new Mock<IConnectionFactory>();
-            fakeConnectionFactory.SetupSequence(m => m.CreateConnection())
-                .Returns(ClosedConnection) // We need to do it like this as we 
use a dictionary of dead connections in 
-                .Returns(ClosedConnection) //   ConnectionPool and the three 
connections need to be different objects
-                .Returns(ClosedConnection);//   for this to work.
-            var pool = CreateConnectionPool(fakeConnectionFactory.Object, 3, 
0);
+            var fakeConnectionFactory = Substitute.For<IConnectionFactory>();
+            fakeConnectionFactory.CreateConnection()
+                .Returns(_ => ClosedConnection,      // We need to do it like 
this as we use a dictionary of dead connections in 
+                    _ => ClosedConnection,    //   ConnectionPool and the 
three connections need to be different objects
+                    _ => ClosedConnection);                  //   for this to 
work.
+            var pool = CreateConnectionPool(fakeConnectionFactory, 3, 0);
             var startEstablishingProblematicConnections = new SemaphoreSlim(0, 
1);
             // Let the pool get one connection that is so slow to open that 
the pool will afterwards try to create two
             //  more connections in parallel.
-            var fakedSlowToEstablishConnection = new Mock<IConnection>();
-            fakedSlowToEstablishConnection.Setup(m => 
m.ConnectAsync(It.IsAny<CancellationToken>()))
-                .Returns(startEstablishingProblematicConnections.WaitAsync);
-            fakeConnectionFactory.Setup(m => m.CreateConnection())
-                .Returns(fakedSlowToEstablishConnection.Object);
+            var fakedSlowToEstablishConnection = Substitute.For<IConnection>();
+            
fakedSlowToEstablishConnection.ConnectAsync(Arg.Any<CancellationToken>())
+                .Returns(async _ => await 
startEstablishingProblematicConnections.WaitAsync());
+            
fakeConnectionFactory.Configure().CreateConnection().Returns(fakedSlowToEstablishConnection);
             // Trigger replacement of closed connections
             try
             {
@@ -333,55 +332,48 @@ namespace Gremlin.Net.UnitTest.Driver
                 // expected as the pool only contain closed connections at 
this point
             }
             
-            var fakedOpenConnection = FakedOpenConnection;
-            var fakedCannotConnectConnection = FakedCannotConnectConnection;
-            fakeConnectionFactory.SetupSequence(m => m.CreateConnection())
-                .Returns(fakedOpenConnection.Object)
-                .Returns(fakedCannotConnectConnection.Object);
+            var fakedOpenConnection = OpenConnection;
+            var fakedCannotConnectConnection = CannotConnectConnection;
+            fakeConnectionFactory.Configure().CreateConnection()
+                .Returns(fakedOpenConnection, fakedCannotConnectConnection);
             // Let the slow to establish connection finish so the pool can try 
to establish the other two connections
             startEstablishingProblematicConnections.Release();
             await Task.Delay(TimeSpan.FromMilliseconds(200));
             
             // Verify that the pool tried to establish both connections and 
then also disposed both, even though one throw an exception
-            fakedOpenConnection.Verify(m => 
m.ConnectAsync(It.IsAny<CancellationToken>()), Times.Once());
-            fakedOpenConnection.Verify(m => m.Dispose(), Times.Once);
-            fakedCannotConnectConnection.Verify(m => 
m.ConnectAsync(It.IsAny<CancellationToken>()), Times.Once);
-            fakedCannotConnectConnection.Verify(m => m.Dispose(), Times.Once);
+            await 
fakedOpenConnection.Received(1).ConnectAsync(Arg.Any<CancellationToken>());
+            fakedOpenConnection.Received(1).Dispose();
+            await 
fakedCannotConnectConnection.Received(1).ConnectAsync(Arg.Any<CancellationToken>());
+            fakedCannotConnectConnection.Received(1).Dispose();
         }
 
-        private static IConnection OpenConnection => 
FakedOpenConnection.Object;
-
-        private static Mock<IConnection> FakedOpenConnection
+        private static IConnection OpenConnection
         {
             get
             {
-                var fakedConnection = new Mock<IConnection>();
-                fakedConnection.Setup(f => f.IsOpen).Returns(true);
+                var fakedConnection = Substitute.For<IConnection>();
+                fakedConnection.IsOpen.Returns(true);
                 return fakedConnection;
             }
         }
-
-        private static IConnection ClosedConnection => 
FakedClosedConnection.Object;
         
-        private static Mock<IConnection> FakedClosedConnection
+        private static IConnection ClosedConnection
         {
             get
             {
-                var fakedConnection = new Mock<IConnection>();
-                fakedConnection.Setup(f => f.IsOpen).Returns(false);
+                var fakedConnection = Substitute.For<IConnection>();
+                fakedConnection.IsOpen.Returns(false);
                 return fakedConnection;
             }
         }
-
-        private static IConnection CannotConnectConnection => 
FakedCannotConnectConnection.Object;
         
-        private static Mock<IConnection> FakedCannotConnectConnection
+        private static IConnection CannotConnectConnection
         {
             get
             {
-                var fakedConnection = new Mock<IConnection>();
-                fakedConnection.Setup(f => f.IsOpen).Returns(false);
-                fakedConnection.Setup(f => 
f.ConnectAsync(It.IsAny<CancellationToken>()))
+                var fakedConnection = Substitute.For<IConnection>();
+                fakedConnection.IsOpen.Returns(false);
+                fakedConnection.ConnectAsync(Arg.Any<CancellationToken>())
                     .Throws(new Exception("Cannot connect to server."));
                 return fakedConnection;
             }
diff --git a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Driver/ConnectionTests.cs 
b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Driver/ConnectionTests.cs
index 44c7105ba2..ef71d235d4 100644
--- a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Driver/ConnectionTests.cs
+++ b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Driver/ConnectionTests.cs
@@ -30,7 +30,9 @@ using Gremlin.Net.Driver;
 using Gremlin.Net.Driver.Exceptions;
 using Gremlin.Net.Driver.Messages;
 using Gremlin.Net.Structure.IO.GraphBinary;
-using Moq;
+using NSubstitute;
+using NSubstitute.ExceptionExtensions;
+using NSubstitute.Extensions;
 using Xunit;
 
 namespace Gremlin.Net.UnitTest.Driver
@@ -40,56 +42,55 @@ namespace Gremlin.Net.UnitTest.Driver
         [Fact]
         public async Task ShouldHandleCloseMessageAfterConnectAsync()
         {
-            var mockedClientWebSocket = new Mock<IClientWebSocket>();
-            mockedClientWebSocket
-                .Setup(m => m.ReceiveAsync(It.IsAny<ArraySegment<byte>>(), 
It.IsAny<CancellationToken>()))
-                .ReturnsAsync(new WebSocketReceiveResult(0, 
WebSocketMessageType.Close, true, WebSocketCloseStatus.MessageTooBig, "Message 
is too large"));
-            mockedClientWebSocket
-                .SetupGet(m => m.Options).Returns(new 
ClientWebSocket().Options);
-
-            Uri uri = new Uri("wss://localhost:8182");
-            Connection connection = GetConnection(mockedClientWebSocket, uri: 
uri);
+            var mockedClientWebSocket = Substitute.For<IClientWebSocket>();
+            mockedClientWebSocket.ReceiveAsync(Arg.Any<ArraySegment<byte>>(), 
Arg.Any<CancellationToken>()).Returns(
+                new WebSocketReceiveResult(0, WebSocketMessageType.Close, 
true, WebSocketCloseStatus.MessageTooBig,
+                    "Message is too large"));
+            mockedClientWebSocket.Options.Returns(new 
ClientWebSocket().Options);
+            var uri = new Uri("wss://localhost:8182");
+            var connection = GetConnection(mockedClientWebSocket, uri: uri);
 
             await connection.ConnectAsync(CancellationToken.None);
 
             Assert.False(connection.IsOpen);
             Assert.Equal(0, connection.NrRequestsInFlight);
-            mockedClientWebSocket.Verify(m => m.ConnectAsync(uri, 
It.IsAny<CancellationToken>()), Times.Once);
-            mockedClientWebSocket.Verify(m => 
m.ReceiveAsync(It.IsAny<ArraySegment<byte>>(), It.IsAny<CancellationToken>()), 
Times.Once);
-            mockedClientWebSocket.Verify(m => 
m.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, 
It.IsAny<CancellationToken>()), Times.Once);
+            await mockedClientWebSocket.Received(1).ConnectAsync(uri, 
Arg.Any<CancellationToken>());
+            await mockedClientWebSocket.Received(1)
+                .ReceiveAsync(Arg.Any<ArraySegment<byte>>(), 
Arg.Any<CancellationToken>());
+            await 
mockedClientWebSocket.Received(1).CloseAsync(WebSocketCloseStatus.NormalClosure,
 string.Empty,
+                Arg.Any<CancellationToken>());
         }
 
         [Fact]
         public async Task 
ShouldThrowIfClosedMessageReceivedWithValidPropertiesAsync()
         {
-            var mockedClientWebSocket = new Mock<IClientWebSocket>();
-            mockedClientWebSocket
-                .SetupGet(m => m.Options).Returns(new 
ClientWebSocket().Options);
+            var mockedClientWebSocket = Substitute.For<IClientWebSocket>();
+            mockedClientWebSocket.Options.Returns(new 
ClientWebSocket().Options);
 
-            WebSocketConnection webSocketConnection = new WebSocketConnection(
-                mockedClientWebSocket.Object,
+            var webSocketConnection = new WebSocketConnection(
+                mockedClientWebSocket,
                 new WebSocketSettings());
 
             // Test all known close statuses
             foreach (Enum closeStatus in 
Enum.GetValues(typeof(WebSocketCloseStatus)))
             {
                 mockedClientWebSocket
-                    .Setup(m => m.ReceiveAsync(It.IsAny<ArraySegment<byte>>(), 
It.IsAny<CancellationToken>()))
-                    .ReturnsAsync(new WebSocketReceiveResult(0, 
WebSocketMessageType.Close, true, (WebSocketCloseStatus)closeStatus, 
closeStatus.ToString()));
+                    .ReceiveAsync(Arg.Any<ArraySegment<byte>>(), 
Arg.Any<CancellationToken>())
+                    .Returns(new WebSocketReceiveResult(0, 
WebSocketMessageType.Close, true, (WebSocketCloseStatus)closeStatus, 
closeStatus.ToString()));
     
                 await 
AssertExpectedConnectionClosedException((WebSocketCloseStatus?)closeStatus, 
closeStatus.ToString(), () => webSocketConnection.ReceiveMessageAsync());
             }
 
             // Test null/empty close property values as well.
             mockedClientWebSocket
-                .Setup(m => m.ReceiveAsync(It.IsAny<ArraySegment<byte>>(), 
It.IsAny<CancellationToken>()))
-                .ReturnsAsync(new WebSocketReceiveResult(0, 
WebSocketMessageType.Close, true, null, null));
+                .ReceiveAsync(Arg.Any<ArraySegment<byte>>(), 
Arg.Any<CancellationToken>())
+                .Returns(new WebSocketReceiveResult(0, 
WebSocketMessageType.Close, true, null, null));
             await AssertExpectedConnectionClosedException(null, null, () => 
webSocketConnection.ReceiveMessageAsync());
             
             mockedClientWebSocket
-                .Setup(m => m.ReceiveAsync(It.IsAny<ArraySegment<byte>>(), 
It.IsAny<CancellationToken>()))
-                .ReturnsAsync(new WebSocketReceiveResult(0, 
WebSocketMessageType.Close, true, null, String.Empty));
-            await AssertExpectedConnectionClosedException(null, String.Empty, 
() => webSocketConnection.ReceiveMessageAsync());
+                .ReceiveAsync(Arg.Any<ArraySegment<byte>>(), 
Arg.Any<CancellationToken>())
+                .Returns(new WebSocketReceiveResult(0, 
WebSocketMessageType.Close, true, null, string.Empty));
+            await AssertExpectedConnectionClosedException(null, string.Empty, 
() => webSocketConnection.ReceiveMessageAsync());
         }
 
         [Fact]
@@ -98,35 +99,37 @@ namespace Gremlin.Net.UnitTest.Driver
             // This is to test that race bugs don't get introduced which would 
cause submitted requests to hang if the
             // connection is being closed/aborted or is not connected. In 
these cases, WebSocket.SendAsync should throw for the underlying
             // websocket is not open and the caller should be notified of that 
failure.
-            var mockedClientWebSocket = new Mock<IClientWebSocket>();
+            var mockedClientWebSocket = Substitute.For<IClientWebSocket>();
 
-            mockedClientWebSocket
-                .SetupGet(m => m.Options).Returns(new 
ClientWebSocket().Options);
+            mockedClientWebSocket.Options.Returns(new 
ClientWebSocket().Options);
 
-            Connection connection = GetConnection(mockedClientWebSocket);
-            RequestMessage request = RequestMessage.Build("gremlin").Create();
+            var connection = GetConnection(mockedClientWebSocket);
+            var request = RequestMessage.Build("gremlin").Create();
 
             // Simulate the SendAsync exception behavior if the underlying 
websocket is closed (see reference 
https://docs.microsoft.com/en-us/dotnet/api/system.net.websockets.clientwebsocket.sendasync?view=net-6.0)
-            mockedClientWebSocket.Setup(m => 
m.SendAsync(It.IsAny<ArraySegment<byte>>(), It.IsAny<WebSocketMessageType>(), 
It.IsAny<bool>(), It.IsAny<CancellationToken>()))
+            mockedClientWebSocket
+                .SendAsync(Arg.Any<ArraySegment<byte>>(), 
Arg.Any<WebSocketMessageType>(), Arg.Any<bool>(),
+                    Arg.Any<CancellationToken>())
                 .ThrowsAsync(new 
ObjectDisposedException(nameof(ClientWebSocket), "Socket closed"));
 
             // Test various closing/closed WebSocketStates with SubmitAsync.
-            mockedClientWebSocket.Setup(m => 
m.State).Returns(WebSocketState.Closed);
+            mockedClientWebSocket.State.Returns(WebSocketState.Closed);
             await Assert.ThrowsAsync<ObjectDisposedException>(() => 
connection.SubmitAsync<dynamic>(request, CancellationToken.None));
 
-            mockedClientWebSocket.Setup(m => 
m.State).Returns(WebSocketState.CloseSent);
+            mockedClientWebSocket.State.Returns(WebSocketState.CloseSent);
             await Assert.ThrowsAsync<ObjectDisposedException>(() => 
connection.SubmitAsync<dynamic>(request, CancellationToken.None));
 
-            mockedClientWebSocket.Setup(m => 
m.State).Returns(WebSocketState.CloseReceived);
+            mockedClientWebSocket.State.Returns(WebSocketState.CloseReceived);
             await Assert.ThrowsAsync<ObjectDisposedException>(() => 
connection.SubmitAsync<dynamic>(request, CancellationToken.None));
 
-            mockedClientWebSocket.Setup(m => 
m.State).Returns(WebSocketState.Aborted);
+            mockedClientWebSocket.State.Returns(WebSocketState.Aborted);
             await Assert.ThrowsAsync<ObjectDisposedException>(() => 
connection.SubmitAsync<dynamic>(request, CancellationToken.None));
 
             // Simulate SendAsync exception behavior if underlying websocket 
is not connected.
-            mockedClientWebSocket.Setup(m => 
m.SendAsync(It.IsAny<ArraySegment<byte>>(), It.IsAny<WebSocketMessageType>(), 
It.IsAny<bool>(), It.IsAny<CancellationToken>()))
-                .ThrowsAsync(new InvalidOperationException("Socket not 
connected"));
-            mockedClientWebSocket.Setup(m => 
m.State).Returns(WebSocketState.Connecting);
+            mockedClientWebSocket
+                .SendAsync(Arg.Any<ArraySegment<byte>>(), 
Arg.Any<WebSocketMessageType>(), Arg.Any<bool>(),
+                    Arg.Any<CancellationToken>()).ThrowsAsync(new 
InvalidOperationException("Socket not connected"));
+            mockedClientWebSocket.State.Returns(WebSocketState.Connecting);
             await Assert.ThrowsAsync<InvalidOperationException>(() => 
connection.SubmitAsync<dynamic>(request, CancellationToken.None));
         }
 
@@ -134,29 +137,27 @@ namespace Gremlin.Net.UnitTest.Driver
         public async Task ShouldHandleCloseMessageForInFlightRequestsAsync()
         {
             // Tests that in-flight requests will get notified if a connection 
close message is received.
-            Uri uri = new Uri("wss://localhost:8182");
-            WebSocketReceiveResult closeResult = new WebSocketReceiveResult(0, 
WebSocketMessageType.Close, true, WebSocketCloseStatus.EndpointUnavailable, 
"Server shutdown");
+            var uri = new Uri("wss://localhost:8182");
+            var closeResult = new WebSocketReceiveResult(0, 
WebSocketMessageType.Close, true, WebSocketCloseStatus.EndpointUnavailable, 
"Server shutdown");
 
-            var receiveSempahore = new SemaphoreSlim(0, 1);
-            var mockedClientWebSocket = new Mock<IClientWebSocket>();
-            mockedClientWebSocket
-                .Setup(m => m.ReceiveAsync(It.IsAny<ArraySegment<byte>>(), 
It.IsAny<CancellationToken>()))
-                .Returns(async () =>
+            var receiveSemaphore = new SemaphoreSlim(0, 1);
+            var mockedClientWebSocket = Substitute.For<IClientWebSocket>();
+            mockedClientWebSocket.ReceiveAsync(Arg.Any<ArraySegment<byte>>(), 
Arg.Any<CancellationToken>())
+                .ReturnsForAnyArgs(async x =>
                 {
-                    await receiveSempahore.WaitAsync();
-                    mockedClientWebSocket.Setup(m => 
m.State).Returns(WebSocketState.CloseReceived);
+                    await receiveSemaphore.WaitAsync();
+                    
mockedClientWebSocket.State.Returns(WebSocketState.CloseReceived);
                     return closeResult;
                 });
-            mockedClientWebSocket.Setup(m => 
m.State).Returns(WebSocketState.Open);
-            mockedClientWebSocket
-                .SetupGet(m => m.Options).Returns(new 
ClientWebSocket().Options);
+            mockedClientWebSocket.State.Returns(WebSocketState.Open);
+            mockedClientWebSocket.Options.Returns(new 
ClientWebSocket().Options);
 
             var connection = GetConnection(mockedClientWebSocket, uri: uri);
             await connection.ConnectAsync(CancellationToken.None);
 
             // Create two in-flight requests that will block on waiting for a 
response.
-            RequestMessage requestMsg1 = 
RequestMessage.Build("gremlin").Create();
-            RequestMessage requestMsg2 = 
RequestMessage.Build("gremlin").Create();
+            var requestMsg1 = RequestMessage.Build("gremlin").Create();
+            var requestMsg2 = RequestMessage.Build("gremlin").Create();
             Task request1 = connection.SubmitAsync<dynamic>(requestMsg1, 
CancellationToken.None);
             Task request2 = connection.SubmitAsync<dynamic>(requestMsg2, 
CancellationToken.None);
 
@@ -164,7 +165,7 @@ namespace Gremlin.Net.UnitTest.Driver
             Assert.Equal(2, connection.NrRequestsInFlight);
 
             // Release the connection close message.
-            receiveSempahore.Release();
+            receiveSemaphore.Release();
 
             // Assert that both requests get notified with the closed 
exception.
             await 
AssertExpectedConnectionClosedException(closeResult.CloseStatus, 
closeResult.CloseStatusDescription, () => request1);
@@ -179,17 +180,18 @@ namespace Gremlin.Net.UnitTest.Driver
 
             Assert.False(connection.IsOpen);
             Assert.Equal(0, connection.NrRequestsInFlight);
-            mockedClientWebSocket.Verify(m => m.ConnectAsync(uri, 
It.IsAny<CancellationToken>()), Times.Once);
-            mockedClientWebSocket.Verify(m => 
m.ReceiveAsync(It.IsAny<ArraySegment<byte>>(), It.IsAny<CancellationToken>()), 
Times.Once);
-            mockedClientWebSocket.Verify(m => 
m.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, 
It.IsAny<CancellationToken>()), Times.Once);
+            await mockedClientWebSocket.Received(1).ConnectAsync(uri, 
Arg.Any<CancellationToken>());
+            await mockedClientWebSocket.Received(1)
+                .ReceiveAsync(Arg.Any<ArraySegment<byte>>(), 
Arg.Any<CancellationToken>());
+            await 
mockedClientWebSocket.Received(1).CloseAsync(WebSocketCloseStatus.NormalClosure,
 string.Empty,
+                Arg.Any<CancellationToken>());
         }
 
         [Fact]
         public async Task ShouldProperlyHandleCancellationForSubmitAsync()
         {
-            var mockedClientWebSocket = new Mock<IClientWebSocket>();
-            mockedClientWebSocket
-                .SetupGet(m => m.Options).Returns(new 
ClientWebSocket().Options);
+            var mockedClientWebSocket = Substitute.For<IClientWebSocket>();
+            mockedClientWebSocket.Options.Returns(new 
ClientWebSocket().Options);
             var connection = GetConnection(mockedClientWebSocket);
             var cts = new CancellationTokenSource();
 
@@ -199,21 +201,18 @@ namespace Gremlin.Net.UnitTest.Driver
             
             await Assert.ThrowsAsync<TaskCanceledException>(async () => await 
task);
             Assert.True(task.IsCanceled);
-            mockedClientWebSocket.Verify(m => 
m.SendAsync(It.IsAny<ArraySegment<byte>>(),
-                It.IsAny<WebSocketMessageType>(), It.IsAny<bool>(), 
cts.Token), Times.Once);
-            mockedClientWebSocket.Verify(
-                m => m.CloseAsync(It.IsAny<WebSocketCloseStatus>(), 
It.IsAny<string>(), It.IsAny<CancellationToken>()),
-                Times.Never);
-            mockedClientWebSocket.Verify(
-                m => m.ReceiveAsync(It.IsAny<ArraySegment<byte>>(), 
cts.Token), Times.Never);
+            await 
mockedClientWebSocket.Received(1).SendAsync(Arg.Any<ArraySegment<byte>>(),
+                Arg.Any<WebSocketMessageType>(), Arg.Any<bool>(), cts.Token);
+            await 
mockedClientWebSocket.DidNotReceive().CloseAsync(Arg.Any<WebSocketCloseStatus>(),
 Arg.Any<string>(),
+                Arg.Any<CancellationToken>());
+            await 
mockedClientWebSocket.DidNotReceive().ReceiveAsync(Arg.Any<ArraySegment<byte>>(),
 cts.Token);
         }
         
         [Fact]
         public async Task 
ShouldProperlyHandleCancellationForSubmitAsyncIfAlreadyCancelled()
         {
-            var mockedClientWebSocket = new Mock<IClientWebSocket>();
-            mockedClientWebSocket
-                .SetupGet(m => m.Options).Returns(new 
ClientWebSocket().Options);
+            var mockedClientWebSocket = Substitute.For<IClientWebSocket>();
+            mockedClientWebSocket.Options.Returns(new 
ClientWebSocket().Options);
             var connection = GetConnection(mockedClientWebSocket);
             var token = new CancellationToken(canceled: true);
 
@@ -222,25 +221,21 @@ namespace Gremlin.Net.UnitTest.Driver
             
             await Assert.ThrowsAsync<TaskCanceledException>(async () => await 
task);
             Assert.True(task.IsCanceled);
-            mockedClientWebSocket.Verify(
-                m => m.SendAsync(It.IsAny<ArraySegment<byte>>(), 
It.IsAny<WebSocketMessageType>(), It.IsAny<bool>(),
-                    It.IsAny<CancellationToken>()), Times.Never);
-            mockedClientWebSocket.Verify(
-                m => m.CloseAsync(It.IsAny<WebSocketCloseStatus>(), 
It.IsAny<string>(), It.IsAny<CancellationToken>()),
-                Times.Never);
-            mockedClientWebSocket.Verify(
-                m => m.ReceiveAsync(It.IsAny<ArraySegment<byte>>(), token), 
Times.Never);
+            await 
mockedClientWebSocket.DidNotReceive().SendAsync(Arg.Any<ArraySegment<byte>>(),
+                Arg.Any<WebSocketMessageType>(), Arg.Any<bool>(), 
Arg.Any<CancellationToken>());
+            await 
mockedClientWebSocket.DidNotReceive().CloseAsync(Arg.Any<WebSocketCloseStatus>(),
 Arg.Any<string>(),
+                Arg.Any<CancellationToken>());
+            await 
mockedClientWebSocket.DidNotReceive().ReceiveAsync(Arg.Any<ArraySegment<byte>>(),
 token);
         }
         
         [Fact]
         public async Task 
ShouldContinueSubmittingOtherMessagesIfOneIsCancelled()
         {
-            var mockedClientWebSocket = new Mock<IClientWebSocket>();
-            mockedClientWebSocket
-                .SetupGet(m => m.Options).Returns(new 
ClientWebSocket().Options);
+            var mockedClientWebSocket = Substitute.For<IClientWebSocket>();
+            mockedClientWebSocket.Options.Returns(new 
ClientWebSocket().Options);
             var tcs = new TaskCompletionSource();
-            mockedClientWebSocket.Setup(m => 
m.SendAsync(It.IsAny<ArraySegment<byte>>(),
-                It.IsAny<WebSocketMessageType>(), It.IsAny<bool>(), 
It.IsAny<CancellationToken>())).Returns(tcs.Task);
+            mockedClientWebSocket.SendAsync(Arg.Any<ArraySegment<byte>>(), 
Arg.Any<WebSocketMessageType>(),
+                Arg.Any<bool>(), 
Arg.Any<CancellationToken>()).Returns(tcs.Task);
             var connection = GetConnection(mockedClientWebSocket);
             var cts = new CancellationTokenSource();
             
@@ -256,27 +251,25 @@ namespace Gremlin.Net.UnitTest.Driver
             await Assert.ThrowsAsync<TaskCanceledException>(async () => await 
taskToCancel);
             Assert.True(taskToCancel.IsCanceled);
             await Task.Delay(TimeSpan.FromMilliseconds(200)); // wait a bit to 
let the messages being sent
-            mockedClientWebSocket.Verify(m => 
m.SendAsync(It.IsAny<ArraySegment<byte>>(),
-                It.IsAny<WebSocketMessageType>(), It.IsAny<bool>(), 
It.IsAny<CancellationToken>()), Times.Exactly(3));
+            await 
mockedClientWebSocket.Received(3).SendAsync(Arg.Any<ArraySegment<byte>>(),
+                Arg.Any<WebSocketMessageType>(), Arg.Any<bool>(), 
Arg.Any<CancellationToken>());
         }
         
         [Fact]
         public async Task 
ShouldContinueSubmittingOtherMessagesIfOneIsAlreadyCancelled()
         {
-            var mockedClientWebSocket = new Mock<IClientWebSocket>();
-            mockedClientWebSocket
-                .SetupGet(m => m.Options).Returns(new 
ClientWebSocket().Options);
+            var mockedClientWebSocket = Substitute.For<IClientWebSocket>();
+            mockedClientWebSocket.Options.Returns(new 
ClientWebSocket().Options);
             var cancelledToken = new CancellationToken(canceled: true);
-            mockedClientWebSocket
-                .Setup(m => m.SendAsync(It.IsAny<ArraySegment<byte>>(), 
It.IsAny<WebSocketMessageType>(),
-                    It.IsAny<bool>(), cancelledToken))
-                .ThrowsAsync(new TaskCanceledException(null, null, 
cancelledToken));
+            mockedClientWebSocket.SendAsync(Arg.Any<ArraySegment<byte>>(), 
Arg.Any<WebSocketMessageType>(),
+                    Arg.Any<bool>(), cancelledToken)
+                .Throws(new TaskCanceledException(null, null, cancelledToken));
             var messageToSend = RequestMessage.Build(string.Empty).Create();
-            var fakeMessageSerializer = new Mock<IMessageSerializer>();
+            var fakeMessageSerializer = Substitute.For<IMessageSerializer>();
             var bytesToSend = new byte[] { 1, 2, 3 };
-            fakeMessageSerializer.Setup(f => 
f.SerializeMessageAsync(messageToSend, It.IsAny<CancellationToken>()))
-                .ReturnsAsync(bytesToSend);
-            var connection = GetConnection(mockedClientWebSocket, 
fakeMessageSerializer.Object);
+            fakeMessageSerializer.SerializeMessageAsync(messageToSend, 
Arg.Any<CancellationToken>())
+                .Returns(bytesToSend);
+            var connection = GetConnection(mockedClientWebSocket, 
fakeMessageSerializer);
             
             var taskToCancel = 
connection.SubmitAsync<object>(RequestMessage.Build(string.Empty).Create(),
                 cancelledToken);
@@ -284,26 +277,26 @@ namespace Gremlin.Net.UnitTest.Driver
             
             await Assert.ThrowsAsync<TaskCanceledException>(async () => await 
taskToCancel);
             Assert.True(taskToCancel.IsCanceled);
-            mockedClientWebSocket.Verify(m => m.SendAsync(bytesToSend,
-                It.IsAny<WebSocketMessageType>(), It.IsAny<bool>(), 
It.IsAny<CancellationToken>()), Times.Exactly(1));
+            await mockedClientWebSocket.Received(1).SendAsync(bytesToSend, 
Arg.Any<WebSocketMessageType>(),
+                Arg.Any<bool>(), Arg.Any<CancellationToken>());
         }
 
         [Fact]
         public async Task ShouldNotProcessReceivedMessageForCancelledRequest()
         {
-            var fakeMessageSerializer = new Mock<IMessageSerializer>();
+            var fakeMessageSerializer = Substitute.For<IMessageSerializer>();
             var receivedBytes = new byte[] { 1, 2, 3 };
             var messageToCancel = RequestMessage.Build(string.Empty).Create();
             var receivedMessage = new ResponseMessage<List<object>>
             {
                 RequestId = messageToCancel.RequestId, Status = new 
ResponseStatus { Code = ResponseStatusCode.Success }
             };
-            fakeMessageSerializer.Setup(f => 
f.DeserializeMessageAsync(receivedBytes, It.IsAny<CancellationToken>()))
-                .ReturnsAsync(receivedMessage);
-            var fakeWebSocketConnection = new Mock<IWebSocketConnection>();
+            fakeMessageSerializer.DeserializeMessageAsync(receivedBytes, 
Arg.Any<CancellationToken>())
+                .Returns(receivedMessage);
+            var fakeWebSocketConnection = 
Substitute.For<IWebSocketConnection>();
             var receiveTaskCompletionSource = new 
TaskCompletionSource<byte[]>();
-            fakeWebSocketConnection.Setup(m => 
m.ReceiveMessageAsync()).Returns(receiveTaskCompletionSource.Task);
-            var connection = GetConnection(fakeWebSocketConnection.Object, 
fakeMessageSerializer.Object);
+            
fakeWebSocketConnection.ReceiveMessageAsync().Returns(receiveTaskCompletionSource.Task);
+            var connection = GetConnection(fakeWebSocketConnection, 
fakeMessageSerializer);
             await connection.ConnectAsync(CancellationToken.None);
             var cts = new CancellationTokenSource();
             
@@ -315,11 +308,11 @@ namespace Gremlin.Net.UnitTest.Driver
             Assert.Equal(0, connection.NrRequestsInFlight);
         }
 
-        private static Connection GetConnection(IMock<IClientWebSocket> 
mockedClientWebSocket,
+        private static Connection GetConnection(IClientWebSocket 
clientWebSocket,
             IMessageSerializer messageSerializer = null, Uri uri = null)
         {
-            return GetConnection(new 
WebSocketConnection(mockedClientWebSocket.Object, new WebSocketSettings()),
-                messageSerializer, uri);
+            return GetConnection(new WebSocketConnection(clientWebSocket, new 
WebSocketSettings()), messageSerializer,
+                uri);
         }
         
         private static Connection GetConnection(IWebSocketConnection 
webSocketConnection,
diff --git 
a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Driver/DriverRemoteConnectionTests.cs
 
b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Driver/DriverRemoteConnectionTests.cs
index 7ed9c96fef..de09081f6b 100644
--- 
a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Driver/DriverRemoteConnectionTests.cs
+++ 
b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Driver/DriverRemoteConnectionTests.cs
@@ -24,7 +24,7 @@
 using System;
 using Gremlin.Net.Driver;
 using Gremlin.Net.Driver.Remote;
-using Moq;
+using NSubstitute;
 using Xunit;
 
 namespace Gremlin.Net.UnitTest.Driver
@@ -34,12 +34,12 @@ namespace Gremlin.Net.UnitTest.Driver
         [Fact]
         public void ShouldDisposeProvidedGremlinClientOnDispose()
         {
-            var gremlinClientMock = new Mock<IGremlinClient>();
-            var driverRemoteConnection = new 
DriverRemoteConnection(gremlinClientMock.Object);
+            var gremlinClient = Substitute.For<IGremlinClient>();
+            var driverRemoteConnection = new 
DriverRemoteConnection(gremlinClient);
 
             driverRemoteConnection.Dispose();
 
-            gremlinClientMock.Verify(m => m.Dispose());
+            gremlinClient.Received().Dispose();
         }
 
         [Fact]
diff --git 
a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Gremlin.Net.UnitTest.csproj 
b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Gremlin.Net.UnitTest.csproj
index 9736882f46..52a7000d9e 100644
--- a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Gremlin.Net.UnitTest.csproj
+++ b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Gremlin.Net.UnitTest.csproj
@@ -14,6 +14,7 @@
   <ItemGroup>
     <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.3" />
     <PackageReference Include="Moq" Version="4.18.4" />
+    <PackageReference Include="NSubstitute" Version="5.0.0" />
     <PackageReference Include="xunit.runner.visualstudio" Version="2.4.5" />
     <PackageReference Include="xunit" Version="2.4.2" />
   </ItemGroup>
diff --git 
a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Process/Remote/RemoteTransactionTests.cs
 
b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Process/Remote/RemoteTransactionTests.cs
index 284566c3f5..45ec88bc28 100644
--- 
a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Process/Remote/RemoteTransactionTests.cs
+++ 
b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Process/Remote/RemoteTransactionTests.cs
@@ -25,7 +25,7 @@ using System;
 using Gremlin.Net.Driver;
 using Gremlin.Net.Driver.Remote;
 using Gremlin.Net.Process.Traversal;
-using Moq;
+using NSubstitute;
 using Xunit;
 
 namespace Gremlin.Net.UnitTest.Process.Remote
@@ -36,7 +36,7 @@ namespace Gremlin.Net.UnitTest.Process.Remote
         public void ShouldNotAllowBeginMoreThanOnce()
         {
             var g = AnonymousTraversalSource.Traversal()
-                .WithRemote(new 
DriverRemoteConnection(Mock.Of<IGremlinClient>()));
+                .WithRemote(new 
DriverRemoteConnection(Substitute.For<IGremlinClient>()));
             var tx = g.Tx();
             tx.Begin();
 
@@ -47,7 +47,7 @@ namespace Gremlin.Net.UnitTest.Process.Remote
         public void ShouldNotSupportChildTransactions()
         {
             var g = AnonymousTraversalSource.Traversal()
-                .WithRemote(new 
DriverRemoteConnection(Mock.Of<IGremlinClient>()));
+                .WithRemote(new 
DriverRemoteConnection(Substitute.For<IGremlinClient>()));
             var tx = g.Tx();
             
             var gtx = tx.Begin();
diff --git 
a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/GraphSONReaderTests.cs
 
b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/GraphSONReaderTests.cs
index 5bc232beed..b42f973bd4 100644
--- 
a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/GraphSONReaderTests.cs
+++ 
b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/GraphSONReaderTests.cs
@@ -28,7 +28,7 @@ using System.Text.Json;
 using Gremlin.Net.Process.Traversal;
 using Gremlin.Net.Structure;
 using Gremlin.Net.Structure.IO.GraphSON;
-using Moq;
+using NSubstitute;
 using Xunit;
 
 namespace Gremlin.Net.UnitTest.Structure.IO.GraphSON
@@ -80,11 +80,11 @@ namespace Gremlin.Net.UnitTest.Structure.IO.GraphSON
         [Fact]
         public void ShouldDeserializeWithCustomDeserializerForCommonType()
         {
-            var customSerializerMock = new Mock<IGraphSONDeserializer>();
+            var customSerializerMock = Substitute.For<IGraphSONDeserializer>();
             const string overrideTypeString = "g:Int64";
             var customSerializerByType = new Dictionary<string, 
IGraphSONDeserializer>
             {
-                {overrideTypeString, customSerializerMock.Object}
+                {overrideTypeString, customSerializerMock}
             };
             var reader = new GraphSON2Reader(customSerializerByType);
 
@@ -92,7 +92,7 @@ namespace Gremlin.Net.UnitTest.Structure.IO.GraphSON
                 
JsonSerializer.Deserialize<JsonElement>($"{{\"@type\":\"{overrideTypeString}\",\"@value\":12}}");
             var deserializedValue = reader.ToObject(jsonElement);
 
-            customSerializerMock.Verify(m => 
m.Objectify(It.IsAny<JsonElement>(), It.IsAny<GraphSONReader>()));
+            customSerializerMock.Received(1).Objectify(Arg.Any<JsonElement>(), 
Arg.Any<GraphSONReader>());
         }
         
         [Theory, MemberData(nameof(Versions))]
diff --git 
a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/GraphSONWriterTests.cs
 
b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/GraphSONWriterTests.cs
index ce593f74ba..9fa612c3db 100644
--- 
a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/GraphSONWriterTests.cs
+++ 
b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Structure/IO/GraphSON/GraphSONWriterTests.cs
@@ -28,7 +28,6 @@ using Gremlin.Net.Process.Traversal;
 using Gremlin.Net.Process.Traversal.Strategy.Decoration;
 using Gremlin.Net.Structure;
 using Gremlin.Net.Structure.IO.GraphSON;
-using Moq;
 using Xunit;
 
 namespace Gremlin.Net.UnitTest.Structure.IO.GraphSON
@@ -202,18 +201,27 @@ namespace Gremlin.Net.UnitTest.Structure.IO.GraphSON
         [Fact]
         public void ShouldSerializeWithCustomSerializerForCommonType()
         {
-            var customSerializerMock = new Mock<IGraphSONSerializer>();
-            customSerializerMock.Setup(m => m.Dictify(It.IsAny<int>(), 
It.IsAny<GraphSONWriter>()))
-                .Returns(new Dictionary<string, dynamic>());
+            var customSerializer = new CustomDummySerializer();
             var customSerializerByType = new Dictionary<Type, 
IGraphSONSerializer>
             {
-                {typeof(int), customSerializerMock.Object}
+                {typeof(int), customSerializer}
             };
             var writer = new GraphSON2Writer(customSerializerByType);
-
+            
             writer.WriteObject(12);
-
-            customSerializerMock.Verify(m => m.Dictify(It.Is<int>(v => v == 
12), It.IsAny<GraphSONWriter>()));
+            
+            Assert.Equal(12, customSerializer.DictifiedLast);
+        }
+        
+        private class CustomDummySerializer : IGraphSONSerializer
+        {
+            public dynamic DictifiedLast { get; private set; }
+            
+            public Dictionary<string, dynamic> Dictify(dynamic objectData, 
GraphSONWriter writer)
+            {
+                DictifiedLast = objectData;
+                return new Dictionary<string, dynamic>();
+            }
         }
 
         [Theory, MemberData(nameof(Versions))]

Reply via email to