diff --git a/src/ApiService/CSharpExtensions.json b/src/ApiService/CSharpExtensions.json index 6cd733e44..da2de0df7 100644 --- a/src/ApiService/CSharpExtensions.json +++ b/src/ApiService/CSharpExtensions.json @@ -8,7 +8,7 @@ "Microsoft.Extensions.Configuration.AzureAppConfiguration.AzureAppConfigurationOptions", "Microsoft.Extensions.Configuration.IConfigurationBuilder", "Microsoft.Extensions.DependencyInjection.IServiceCollection", - "Moq.Language.Flow.IReturnsResult", + "NSubstitute.Core.ConfiguredCall", "System.Text.StringBuilder" ] } diff --git a/src/ApiService/IntegrationTests/Fakes/TestHttpRequestData.cs b/src/ApiService/IntegrationTests/Fakes/TestHttpRequestData.cs index b7c2cdf9f..7732b2ed0 100644 --- a/src/ApiService/IntegrationTests/Fakes/TestHttpRequestData.cs +++ b/src/ApiService/IntegrationTests/Fakes/TestHttpRequestData.cs @@ -7,7 +7,7 @@ using Azure.Core.Serialization; using Microsoft.Azure.Functions.Worker; using Microsoft.Azure.Functions.Worker.Http; using Microsoft.Extensions.Options; -using Moq; +using NSubstitute; namespace IntegrationTests.Fakes; @@ -35,10 +35,10 @@ sealed class TestHttpRequestData : HttpRequestData { private static FunctionContext NewFunctionContext() { // mocking this out at the moment since there’s no way to create a subclass - var mock = new Mock(); + var functionContext = Substitute.For(); var services = new TestServices(); - mock.SetupGet(fc => fc.InstanceServices).Returns(services); - return mock.Object; + functionContext.InstanceServices.Returns(services); + return functionContext; } public static TestHttpRequestData FromJson(string method, T obj) diff --git a/src/ApiService/IntegrationTests/IntegrationTests.csproj b/src/ApiService/IntegrationTests/IntegrationTests.csproj index de7af7b1a..01a032364 100644 --- a/src/ApiService/IntegrationTests/IntegrationTests.csproj +++ b/src/ApiService/IntegrationTests/IntegrationTests.csproj @@ -11,7 +11,6 @@ all - diff --git a/src/ApiService/IntegrationTests/packages.lock.json b/src/ApiService/IntegrationTests/packages.lock.json index 1914f9d31..37fd1215b 100644 --- a/src/ApiService/IntegrationTests/packages.lock.json +++ b/src/ApiService/IntegrationTests/packages.lock.json @@ -33,15 +33,6 @@ "Microsoft.TestPlatform.TestHost": "17.6.2" } }, - "Moq": { - "type": "Direct", - "requested": "[4.18.4, )", - "resolved": "4.18.4", - "contentHash": "IOo+W51+7Afnb0noltJrKxPBSfsgMzTKCw+Re5AMx8l/vBbAbMDOynLik4+lBYIWDJSO0uV7Zdqt7cNb6RZZ+A==", - "dependencies": { - "Castle.Core": "5.1.1" - } - }, "System.Security.Cryptography.Pkcs": { "type": "Direct", "requested": "[7.0.2, )", @@ -225,8 +216,8 @@ }, "Castle.Core": { "type": "Transitive", - "resolved": "5.1.1", - "contentHash": "rpYtIczkzGpf+EkZgDr9CClTdemhsrwA/W5hMoPjLkRFnXzH44zDLoovXeKtmxb1ykXK9aJVODSpiJml8CTw2g==", + "resolved": "5.0.0", + "contentHash": "edc8jjyXqzzy8jFdhs36FZdwmlDDTgqPb2Zy1Q5F/f2uAc88bu/VS/0Tpvgupmpl9zJOvOo5ZizVANb0ltN1NQ==", "dependencies": { "System.Diagnostics.EventLog": "6.0.0" } @@ -1240,6 +1231,14 @@ "Newtonsoft.Json": "10.0.1" } }, + "NSubstitute": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "CWGy4oXvcJcZzL7m5Rr/eMSejFXMDq1RRMlsbL6eltS3AuN/d8GH3ZzUcuStQcCSlcx+hpsgTxdnb3lhozWG6w==", + "dependencies": { + "Castle.Core": "5.0.0" + } + }, "NuGet.Frameworks": { "type": "Transitive", "resolved": "6.5.0", @@ -2563,7 +2562,7 @@ "FsCheck": "[2.16.5, )", "FsCheck.Xunit": "[2.16.5, )", "Microsoft.NET.Test.Sdk": "[17.6.2, )", - "Moq": "[4.18.4, )", + "NSubstitute": "[5.0.0, )", "System.Security.Cryptography.Pkcs": "[7.0.2, )", "xunit": "[2.5.0, )" } diff --git a/src/ApiService/Tests/OrmTest.cs b/src/ApiService/Tests/OrmTest.cs index c84306bb9..c86faaa29 100644 --- a/src/ApiService/Tests/OrmTest.cs +++ b/src/ApiService/Tests/OrmTest.cs @@ -10,7 +10,6 @@ using Azure.Data.Tables; using FluentAssertions; using Microsoft.OneFuzz.Service; using Microsoft.OneFuzz.Service.OneFuzzLib.Orm; -using Moq; using Xunit; using Task = System.Threading.Tasks.Task; diff --git a/src/ApiService/Tests/Tests.csproj b/src/ApiService/Tests/Tests.csproj index d1c3d6306..dac145a88 100644 --- a/src/ApiService/Tests/Tests.csproj +++ b/src/ApiService/Tests/Tests.csproj @@ -12,7 +12,7 @@ - + diff --git a/src/ApiService/Tests/TimerReproTests.cs b/src/ApiService/Tests/TimerReproTests.cs index 19be1fff6..eebfda26d 100644 --- a/src/ApiService/Tests/TimerReproTests.cs +++ b/src/ApiService/Tests/TimerReproTests.cs @@ -1,74 +1,59 @@ using System; -using System.Collections.Generic; using System.Linq; using Microsoft.Azure.Functions.Worker; using Microsoft.Extensions.Logging; using Microsoft.OneFuzz.Service; using Microsoft.OneFuzz.Service.Functions; -using Moq; +using NSubstitute; using Xunit; namespace Tests; public class TimerReproTests { private readonly ILogger _log; - private readonly Mock _mockCtx; - private readonly Mock _mockReproOperations; + private readonly IOnefuzzContext _mockCtx; + private readonly IReproOperations _mockReproOperations; public TimerReproTests() { - _mockCtx = new Mock(); - _mockReproOperations = new Mock(); + _mockReproOperations = Substitute.For(); + _mockReproOperations.SearchExpired().Returns(AsyncEnumerable.Empty()); + _mockReproOperations.SearchStates(VmStateHelper.NeedsWork).Returns(AsyncEnumerable.Empty()); - _mockReproOperations.Setup(x => x.SearchExpired()) - .Returns(AsyncEnumerable.Empty()); - _mockReproOperations.Setup(x => x.SearchStates(VmStateHelper.NeedsWork)) - .Returns(AsyncEnumerable.Empty()); + _mockCtx = Substitute.For(); + _mockCtx.ReproOperations.Returns(_mockReproOperations); - _log = new Mock>().Object; + _log = Substitute.For>(); } [Fact] public async System.Threading.Tasks.Task NoExpiredRepros() { - _mockReproOperations.Setup(x => x.SearchExpired()) - .Returns(AsyncEnumerable.Empty()); - _mockCtx.Setup(x => x.ReproOperations) - .Returns(_mockReproOperations.Object); - - var timerRepro = new TimerRepro(_log, _mockCtx.Object); + var timerRepro = new TimerRepro(_log, _mockCtx); await timerRepro.Run(new TimerInfo()); - _mockReproOperations.Verify(x => x.Stopping(It.IsAny()), Times.Never()); + _ = await _mockReproOperations.DidNotReceive().Stopping(Arg.Any()); } [Fact] public async System.Threading.Tasks.Task ExpiredRepro() { - _mockReproOperations.Setup(x => x.SearchExpired()) - .Returns(new List { - GenerateRepro() - }.ToAsyncEnumerable()); + _mockReproOperations.SearchExpired() + .Returns(new[] { GenerateRepro() }.ToAsyncEnumerable()); - _mockCtx.Setup(x => x.ReproOperations) - .Returns(_mockReproOperations.Object); - - var timerRepro = new TimerRepro(_log, _mockCtx.Object); + var timerRepro = new TimerRepro(_log, _mockCtx); await timerRepro.Run(new TimerInfo()); - _mockReproOperations.Verify(x => x.Stopping(It.IsAny()), Times.Once()); + _ = await _mockReproOperations.Received().Stopping(Arg.Any()); } [Fact] public async System.Threading.Tasks.Task NoNeedsWorkRepros() { - _mockReproOperations.Setup(x => x.SearchStates(VmStateHelper.NeedsWork)) + _mockReproOperations.SearchStates(VmStateHelper.NeedsWork) .Returns(AsyncEnumerable.Empty()); - _mockCtx.Setup(x => x.ReproOperations) - .Returns(_mockReproOperations.Object); - - var timerRepro = new TimerRepro(_log, _mockCtx.Object); + var timerRepro = new TimerRepro(_log, _mockCtx); await timerRepro.Run(new TimerInfo()); - _mockReproOperations.Verify(x => x.ProcessStateUpdates(It.IsAny(), It.IsAny()), Times.Never()); + _ = await _mockReproOperations.DidNotReceive().ProcessStateUpdates(Arg.Any(), Arg.Any()); } [Fact] @@ -76,24 +61,16 @@ public class TimerReproTests { var expiredVm = GenerateRepro(); var notExpiredVm = GenerateRepro(); - _mockReproOperations.Setup(x => x.SearchExpired()) - .Returns(new List { - expiredVm - }.ToAsyncEnumerable()); + _mockReproOperations.SearchExpired() + .Returns(new[] { expiredVm }.ToAsyncEnumerable()); - _mockReproOperations.Setup(x => x.SearchStates(VmStateHelper.NeedsWork)) - .Returns(new List { - expiredVm, - notExpiredVm - }.ToAsyncEnumerable()); + _mockReproOperations.SearchStates(VmStateHelper.NeedsWork) + .Returns(new[] { expiredVm, notExpiredVm }.ToAsyncEnumerable()); - _mockCtx.Setup(x => x.ReproOperations) - .Returns(_mockReproOperations.Object); - - var timerRepro = new TimerRepro(_log, _mockCtx.Object); + var timerRepro = new TimerRepro(_log, _mockCtx); await timerRepro.Run(new TimerInfo()); - _mockReproOperations.Verify(x => x.ProcessStateUpdates(It.IsAny(), It.IsAny()), Times.Once()); + _ = await _mockReproOperations.Received().ProcessStateUpdates(Arg.Any(), Arg.Any()); } private static Repro GenerateRepro() { diff --git a/src/ApiService/Tests/packages.lock.json b/src/ApiService/Tests/packages.lock.json index 8ed617827..1c8392cb4 100644 --- a/src/ApiService/Tests/packages.lock.json +++ b/src/ApiService/Tests/packages.lock.json @@ -52,13 +52,13 @@ "Microsoft.TestPlatform.TestHost": "17.6.2" } }, - "Moq": { + "NSubstitute": { "type": "Direct", - "requested": "[4.18.4, )", - "resolved": "4.18.4", - "contentHash": "IOo+W51+7Afnb0noltJrKxPBSfsgMzTKCw+Re5AMx8l/vBbAbMDOynLik4+lBYIWDJSO0uV7Zdqt7cNb6RZZ+A==", + "requested": "[5.0.0, )", + "resolved": "5.0.0", + "contentHash": "CWGy4oXvcJcZzL7m5Rr/eMSejFXMDq1RRMlsbL6eltS3AuN/d8GH3ZzUcuStQcCSlcx+hpsgTxdnb3lhozWG6w==", "dependencies": { - "Castle.Core": "5.1.1" + "Castle.Core": "5.0.0" } }, "System.Security.Cryptography.Pkcs": { @@ -244,8 +244,8 @@ }, "Castle.Core": { "type": "Transitive", - "resolved": "5.1.1", - "contentHash": "rpYtIczkzGpf+EkZgDr9CClTdemhsrwA/W5hMoPjLkRFnXzH44zDLoovXeKtmxb1ykXK9aJVODSpiJml8CTw2g==", + "resolved": "5.0.0", + "contentHash": "edc8jjyXqzzy8jFdhs36FZdwmlDDTgqPb2Zy1Q5F/f2uAc88bu/VS/0Tpvgupmpl9zJOvOo5ZizVANb0ltN1NQ==", "dependencies": { "System.Diagnostics.EventLog": "6.0.0" }