Switch to NSubstitute (#3402)

This commit is contained in:
George Pollard
2023-08-11 01:04:30 +12:00
committed by GitHub
parent a364051923
commit ec6ce0f1b0
8 changed files with 48 additions and 74 deletions

View File

@ -8,7 +8,7 @@
"Microsoft.Extensions.Configuration.AzureAppConfiguration.AzureAppConfigurationOptions", "Microsoft.Extensions.Configuration.AzureAppConfiguration.AzureAppConfigurationOptions",
"Microsoft.Extensions.Configuration.IConfigurationBuilder", "Microsoft.Extensions.Configuration.IConfigurationBuilder",
"Microsoft.Extensions.DependencyInjection.IServiceCollection", "Microsoft.Extensions.DependencyInjection.IServiceCollection",
"Moq.Language.Flow.IReturnsResult", "NSubstitute.Core.ConfiguredCall",
"System.Text.StringBuilder" "System.Text.StringBuilder"
] ]
} }

View File

@ -7,7 +7,7 @@ using Azure.Core.Serialization;
using Microsoft.Azure.Functions.Worker; using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Http; using Microsoft.Azure.Functions.Worker.Http;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Moq; using NSubstitute;
namespace IntegrationTests.Fakes; namespace IntegrationTests.Fakes;
@ -35,10 +35,10 @@ sealed class TestHttpRequestData : HttpRequestData {
private static FunctionContext NewFunctionContext() { private static FunctionContext NewFunctionContext() {
// mocking this out at the moment since theres no way to create a subclass // mocking this out at the moment since theres no way to create a subclass
var mock = new Mock<FunctionContext>(); var functionContext = Substitute.For<FunctionContext>();
var services = new TestServices(); var services = new TestServices();
mock.SetupGet(fc => fc.InstanceServices).Returns(services); functionContext.InstanceServices.Returns(services);
return mock.Object; return functionContext;
} }
public static TestHttpRequestData FromJson<T>(string method, T obj) public static TestHttpRequestData FromJson<T>(string method, T obj)

View File

@ -11,7 +11,6 @@
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
</PackageReference> </PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.2" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.2" />
<PackageReference Include="Moq" Version="4.18.4" />
<PackageReference Include="System.Security.Cryptography.Pkcs" Version="7.0.2" /> <PackageReference Include="System.Security.Cryptography.Pkcs" Version="7.0.2" />
<PackageReference Include="xunit" Version="2.5.0" /> <PackageReference Include="xunit" Version="2.5.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.0"> <PackageReference Include="xunit.runner.visualstudio" Version="2.5.0">

View File

@ -33,15 +33,6 @@
"Microsoft.TestPlatform.TestHost": "17.6.2" "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": { "System.Security.Cryptography.Pkcs": {
"type": "Direct", "type": "Direct",
"requested": "[7.0.2, )", "requested": "[7.0.2, )",
@ -225,8 +216,8 @@
}, },
"Castle.Core": { "Castle.Core": {
"type": "Transitive", "type": "Transitive",
"resolved": "5.1.1", "resolved": "5.0.0",
"contentHash": "rpYtIczkzGpf+EkZgDr9CClTdemhsrwA/W5hMoPjLkRFnXzH44zDLoovXeKtmxb1ykXK9aJVODSpiJml8CTw2g==", "contentHash": "edc8jjyXqzzy8jFdhs36FZdwmlDDTgqPb2Zy1Q5F/f2uAc88bu/VS/0Tpvgupmpl9zJOvOo5ZizVANb0ltN1NQ==",
"dependencies": { "dependencies": {
"System.Diagnostics.EventLog": "6.0.0" "System.Diagnostics.EventLog": "6.0.0"
} }
@ -1240,6 +1231,14 @@
"Newtonsoft.Json": "10.0.1" "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": { "NuGet.Frameworks": {
"type": "Transitive", "type": "Transitive",
"resolved": "6.5.0", "resolved": "6.5.0",
@ -2563,7 +2562,7 @@
"FsCheck": "[2.16.5, )", "FsCheck": "[2.16.5, )",
"FsCheck.Xunit": "[2.16.5, )", "FsCheck.Xunit": "[2.16.5, )",
"Microsoft.NET.Test.Sdk": "[17.6.2, )", "Microsoft.NET.Test.Sdk": "[17.6.2, )",
"Moq": "[4.18.4, )", "NSubstitute": "[5.0.0, )",
"System.Security.Cryptography.Pkcs": "[7.0.2, )", "System.Security.Cryptography.Pkcs": "[7.0.2, )",
"xunit": "[2.5.0, )" "xunit": "[2.5.0, )"
} }

View File

@ -10,7 +10,6 @@ using Azure.Data.Tables;
using FluentAssertions; using FluentAssertions;
using Microsoft.OneFuzz.Service; using Microsoft.OneFuzz.Service;
using Microsoft.OneFuzz.Service.OneFuzzLib.Orm; using Microsoft.OneFuzz.Service.OneFuzzLib.Orm;
using Moq;
using Xunit; using Xunit;
using Task = System.Threading.Tasks.Task; using Task = System.Threading.Tasks.Task;

View File

@ -12,7 +12,7 @@
<PackageReference Include="FsCheck" Version="2.16.5" /> <PackageReference Include="FsCheck" Version="2.16.5" />
<PackageReference Include="FsCheck.Xunit" Version="2.16.5" /> <PackageReference Include="FsCheck.Xunit" Version="2.16.5" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.2" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.2" />
<PackageReference Include="Moq" Version="4.18.4" /> <PackageReference Include="NSubstitute" Version="5.0.0" />
<PackageReference Include="System.Security.Cryptography.Pkcs" Version="7.0.2" /> <PackageReference Include="System.Security.Cryptography.Pkcs" Version="7.0.2" />
<PackageReference Include="xunit" Version="2.5.0" /> <PackageReference Include="xunit" Version="2.5.0" />
<PackageReference Include="FluentAssertions" Version="6.11.0" /> <PackageReference Include="FluentAssertions" Version="6.11.0" />

View File

@ -1,74 +1,59 @@
using System; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using Microsoft.Azure.Functions.Worker; using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.OneFuzz.Service; using Microsoft.OneFuzz.Service;
using Microsoft.OneFuzz.Service.Functions; using Microsoft.OneFuzz.Service.Functions;
using Moq; using NSubstitute;
using Xunit; using Xunit;
namespace Tests; namespace Tests;
public class TimerReproTests { public class TimerReproTests {
private readonly ILogger<TimerRepro> _log; private readonly ILogger<TimerRepro> _log;
private readonly Mock<IOnefuzzContext> _mockCtx; private readonly IOnefuzzContext _mockCtx;
private readonly Mock<IReproOperations> _mockReproOperations; private readonly IReproOperations _mockReproOperations;
public TimerReproTests() { public TimerReproTests() {
_mockCtx = new Mock<IOnefuzzContext>();
_mockReproOperations = new Mock<IReproOperations>(); _mockReproOperations = Substitute.For<IReproOperations>();
_mockReproOperations.SearchExpired().Returns(AsyncEnumerable.Empty<Repro>());
_mockReproOperations.SearchStates(VmStateHelper.NeedsWork).Returns(AsyncEnumerable.Empty<Repro>());
_mockReproOperations.Setup(x => x.SearchExpired()) _mockCtx = Substitute.For<IOnefuzzContext>();
.Returns(AsyncEnumerable.Empty<Repro>()); _mockCtx.ReproOperations.Returns(_mockReproOperations);
_mockReproOperations.Setup(x => x.SearchStates(VmStateHelper.NeedsWork))
.Returns(AsyncEnumerable.Empty<Repro>());
_log = new Mock<ILogger<TimerRepro>>().Object; _log = Substitute.For<ILogger<TimerRepro>>();
} }
[Fact] [Fact]
public async System.Threading.Tasks.Task NoExpiredRepros() { public async System.Threading.Tasks.Task NoExpiredRepros() {
_mockReproOperations.Setup(x => x.SearchExpired())
.Returns(AsyncEnumerable.Empty<Repro>());
_mockCtx.Setup(x => x.ReproOperations) var timerRepro = new TimerRepro(_log, _mockCtx);
.Returns(_mockReproOperations.Object);
var timerRepro = new TimerRepro(_log, _mockCtx.Object);
await timerRepro.Run(new TimerInfo()); await timerRepro.Run(new TimerInfo());
_mockReproOperations.Verify(x => x.Stopping(It.IsAny<Repro>()), Times.Never()); _ = await _mockReproOperations.DidNotReceive().Stopping(Arg.Any<Repro>());
} }
[Fact] [Fact]
public async System.Threading.Tasks.Task ExpiredRepro() { public async System.Threading.Tasks.Task ExpiredRepro() {
_mockReproOperations.Setup(x => x.SearchExpired()) _mockReproOperations.SearchExpired()
.Returns(new List<Repro> { .Returns(new[] { GenerateRepro() }.ToAsyncEnumerable());
GenerateRepro()
}.ToAsyncEnumerable());
_mockCtx.Setup(x => x.ReproOperations) var timerRepro = new TimerRepro(_log, _mockCtx);
.Returns(_mockReproOperations.Object);
var timerRepro = new TimerRepro(_log, _mockCtx.Object);
await timerRepro.Run(new TimerInfo()); await timerRepro.Run(new TimerInfo());
_mockReproOperations.Verify(x => x.Stopping(It.IsAny<Repro>()), Times.Once()); _ = await _mockReproOperations.Received().Stopping(Arg.Any<Repro>());
} }
[Fact] [Fact]
public async System.Threading.Tasks.Task NoNeedsWorkRepros() { public async System.Threading.Tasks.Task NoNeedsWorkRepros() {
_mockReproOperations.Setup(x => x.SearchStates(VmStateHelper.NeedsWork)) _mockReproOperations.SearchStates(VmStateHelper.NeedsWork)
.Returns(AsyncEnumerable.Empty<Repro>()); .Returns(AsyncEnumerable.Empty<Repro>());
_mockCtx.Setup(x => x.ReproOperations) var timerRepro = new TimerRepro(_log, _mockCtx);
.Returns(_mockReproOperations.Object);
var timerRepro = new TimerRepro(_log, _mockCtx.Object);
await timerRepro.Run(new TimerInfo()); await timerRepro.Run(new TimerInfo());
_mockReproOperations.Verify(x => x.ProcessStateUpdates(It.IsAny<Repro>(), It.IsAny<int>()), Times.Never()); _ = await _mockReproOperations.DidNotReceive().ProcessStateUpdates(Arg.Any<Repro>(), Arg.Any<int>());
} }
[Fact] [Fact]
@ -76,24 +61,16 @@ public class TimerReproTests {
var expiredVm = GenerateRepro(); var expiredVm = GenerateRepro();
var notExpiredVm = GenerateRepro(); var notExpiredVm = GenerateRepro();
_mockReproOperations.Setup(x => x.SearchExpired()) _mockReproOperations.SearchExpired()
.Returns(new List<Repro> { .Returns(new[] { expiredVm }.ToAsyncEnumerable());
expiredVm
}.ToAsyncEnumerable());
_mockReproOperations.Setup(x => x.SearchStates(VmStateHelper.NeedsWork)) _mockReproOperations.SearchStates(VmStateHelper.NeedsWork)
.Returns(new List<Repro> { .Returns(new[] { expiredVm, notExpiredVm }.ToAsyncEnumerable());
expiredVm,
notExpiredVm
}.ToAsyncEnumerable());
_mockCtx.Setup(x => x.ReproOperations) var timerRepro = new TimerRepro(_log, _mockCtx);
.Returns(_mockReproOperations.Object);
var timerRepro = new TimerRepro(_log, _mockCtx.Object);
await timerRepro.Run(new TimerInfo()); await timerRepro.Run(new TimerInfo());
_mockReproOperations.Verify(x => x.ProcessStateUpdates(It.IsAny<Repro>(), It.IsAny<int>()), Times.Once()); _ = await _mockReproOperations.Received().ProcessStateUpdates(Arg.Any<Repro>(), Arg.Any<int>());
} }
private static Repro GenerateRepro() { private static Repro GenerateRepro() {

View File

@ -52,13 +52,13 @@
"Microsoft.TestPlatform.TestHost": "17.6.2" "Microsoft.TestPlatform.TestHost": "17.6.2"
} }
}, },
"Moq": { "NSubstitute": {
"type": "Direct", "type": "Direct",
"requested": "[4.18.4, )", "requested": "[5.0.0, )",
"resolved": "4.18.4", "resolved": "5.0.0",
"contentHash": "IOo+W51+7Afnb0noltJrKxPBSfsgMzTKCw+Re5AMx8l/vBbAbMDOynLik4+lBYIWDJSO0uV7Zdqt7cNb6RZZ+A==", "contentHash": "CWGy4oXvcJcZzL7m5Rr/eMSejFXMDq1RRMlsbL6eltS3AuN/d8GH3ZzUcuStQcCSlcx+hpsgTxdnb3lhozWG6w==",
"dependencies": { "dependencies": {
"Castle.Core": "5.1.1" "Castle.Core": "5.0.0"
} }
}, },
"System.Security.Cryptography.Pkcs": { "System.Security.Cryptography.Pkcs": {
@ -244,8 +244,8 @@
}, },
"Castle.Core": { "Castle.Core": {
"type": "Transitive", "type": "Transitive",
"resolved": "5.1.1", "resolved": "5.0.0",
"contentHash": "rpYtIczkzGpf+EkZgDr9CClTdemhsrwA/W5hMoPjLkRFnXzH44zDLoovXeKtmxb1ykXK9aJVODSpiJml8CTw2g==", "contentHash": "edc8jjyXqzzy8jFdhs36FZdwmlDDTgqPb2Zy1Q5F/f2uAc88bu/VS/0Tpvgupmpl9zJOvOo5ZizVANb0ltN1NQ==",
"dependencies": { "dependencies": {
"System.Diagnostics.EventLog": "6.0.0" "System.Diagnostics.EventLog": "6.0.0"
} }