Skip to content
This repository has been archived by the owner on Nov 1, 2023. It is now read-only.

Commit

Permalink
Switch to NSubstitute (#3402)
Browse files Browse the repository at this point in the history
  • Loading branch information
Porges authored Aug 10, 2023
1 parent a364051 commit ec6ce0f
Show file tree
Hide file tree
Showing 8 changed files with 48 additions and 74 deletions.
2 changes: 1 addition & 1 deletion src/ApiService/CSharpExtensions.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
]
}
Expand Down
8 changes: 4 additions & 4 deletions src/ApiService/IntegrationTests/Fakes/TestHttpRequestData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Http;
using Microsoft.Extensions.Options;
using Moq;
using NSubstitute;

namespace IntegrationTests.Fakes;

Expand Down Expand Up @@ -35,10 +35,10 @@ sealed class TestOptions : IOptions<WorkerOptions> {

private static FunctionContext NewFunctionContext() {
// mocking this out at the moment since there’s no way to create a subclass
var mock = new Mock<FunctionContext>();
var functionContext = Substitute.For<FunctionContext>();
var services = new TestServices();
mock.SetupGet(fc => fc.InstanceServices).Returns(services);
return mock.Object;
functionContext.InstanceServices.Returns(services);
return functionContext;
}

public static TestHttpRequestData FromJson<T>(string method, T obj)
Expand Down
1 change: 0 additions & 1 deletion src/ApiService/IntegrationTests/IntegrationTests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<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="xunit" Version="2.5.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.0">
Expand Down
23 changes: 11 additions & 12 deletions src/ApiService/IntegrationTests/packages.lock.json
Original file line number Diff line number Diff line change
Expand Up @@ -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, )",
Expand Down Expand Up @@ -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"
}
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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, )"
}
Expand Down
1 change: 0 additions & 1 deletion src/ApiService/Tests/OrmTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
using FluentAssertions;
using Microsoft.OneFuzz.Service;
using Microsoft.OneFuzz.Service.OneFuzzLib.Orm;
using Moq;
using Xunit;
using Task = System.Threading.Tasks.Task;

Expand Down
2 changes: 1 addition & 1 deletion src/ApiService/Tests/Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<PackageReference Include="FsCheck" Version="2.16.5" />
<PackageReference Include="FsCheck.Xunit" Version="2.16.5" />
<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="xunit" Version="2.5.0" />
<PackageReference Include="FluentAssertions" Version="6.11.0" />
Expand Down
71 changes: 24 additions & 47 deletions src/ApiService/Tests/TimerReproTests.cs
Original file line number Diff line number Diff line change
@@ -1,99 +1,76 @@
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<TimerRepro> _log;
private readonly Mock<IOnefuzzContext> _mockCtx;
private readonly Mock<IReproOperations> _mockReproOperations;
private readonly IOnefuzzContext _mockCtx;
private readonly IReproOperations _mockReproOperations;

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())
.Returns(AsyncEnumerable.Empty<Repro>());
_mockReproOperations.Setup(x => x.SearchStates(VmStateHelper.NeedsWork))
.Returns(AsyncEnumerable.Empty<Repro>());
_mockCtx = Substitute.For<IOnefuzzContext>();
_mockCtx.ReproOperations.Returns(_mockReproOperations);

_log = new Mock<ILogger<TimerRepro>>().Object;
_log = Substitute.For<ILogger<TimerRepro>>();
}

[Fact]
public async System.Threading.Tasks.Task NoExpiredRepros() {
_mockReproOperations.Setup(x => x.SearchExpired())
.Returns(AsyncEnumerable.Empty<Repro>());

_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<Repro>()), Times.Never());
_ = await _mockReproOperations.DidNotReceive().Stopping(Arg.Any<Repro>());
}

[Fact]
public async System.Threading.Tasks.Task ExpiredRepro() {
_mockReproOperations.Setup(x => x.SearchExpired())
.Returns(new List<Repro> {
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<Repro>()), Times.Once());
_ = await _mockReproOperations.Received().Stopping(Arg.Any<Repro>());
}

[Fact]
public async System.Threading.Tasks.Task NoNeedsWorkRepros() {
_mockReproOperations.Setup(x => x.SearchStates(VmStateHelper.NeedsWork))
_mockReproOperations.SearchStates(VmStateHelper.NeedsWork)
.Returns(AsyncEnumerable.Empty<Repro>());

_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<Repro>(), It.IsAny<int>()), Times.Never());
_ = await _mockReproOperations.DidNotReceive().ProcessStateUpdates(Arg.Any<Repro>(), Arg.Any<int>());
}

[Fact]
public async System.Threading.Tasks.Task DontProcessExpiredVms() {
var expiredVm = GenerateRepro();
var notExpiredVm = GenerateRepro();

_mockReproOperations.Setup(x => x.SearchExpired())
.Returns(new List<Repro> {
expiredVm
}.ToAsyncEnumerable());

_mockReproOperations.Setup(x => x.SearchStates(VmStateHelper.NeedsWork))
.Returns(new List<Repro> {
expiredVm,
notExpiredVm
}.ToAsyncEnumerable());
_mockReproOperations.SearchExpired()
.Returns(new[] { expiredVm }.ToAsyncEnumerable());

_mockCtx.Setup(x => x.ReproOperations)
.Returns(_mockReproOperations.Object);
_mockReproOperations.SearchStates(VmStateHelper.NeedsWork)
.Returns(new[] { expiredVm, notExpiredVm }.ToAsyncEnumerable());

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<Repro>(), It.IsAny<int>()), Times.Once());
_ = await _mockReproOperations.Received().ProcessStateUpdates(Arg.Any<Repro>(), Arg.Any<int>());
}

private static Repro GenerateRepro() {
Expand Down
14 changes: 7 additions & 7 deletions src/ApiService/Tests/packages.lock.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": {
Expand Down Expand Up @@ -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"
}
Expand Down

0 comments on commit ec6ce0f

Please sign in to comment.