Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Switch from Moq to NSubstitute in Csla.Blazor.WebAssembly.Tests
This commit represents a significant shift in the mocking framework used for unit testing in the `Csla.Blazor.WebAssembly.Tests.csproj` project. The `Moq` package has been replaced with `NSubstitute` in the project file and throughout the `SessionManagerTests.cs` file. This includes changes in the way mocks are created, set up, and how return values are specified for mocked methods and properties.

Additionally, a new `TestHttpMessageHandler` class has been added to `SessionManagerTests.cs` to mock the behavior of an `HttpClient`. The `GetHttpClient` method has been updated to use this new class, aligning with the switch from `Moq` to `NSubstitute`.
  • Loading branch information
luizbicalhoagl committed May 7, 2024
commit b6c01b9ffac17e7fc3e80b1a95b44a5cee34aa7c
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
<PackageReference Include="Moq" Version="4.20.70" />
<PackageReference Include="MSTest.TestAdapter" Version="3.3.1" />
<PackageReference Include="MSTest.TestFramework" Version="3.3.1" />
<PackageReference Include="coverlet.collector" Version="6.0.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="NSubstitute" Version="5.1.0" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)'=='netcoreapp3.1'">
Expand Down
83 changes: 34 additions & 49 deletions Source/Csla.Blazor.WebAssembly.Tests/SessionManagerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,16 @@
using System.Threading.Tasks;
using Csla.Blazor.WebAssembly.State;
using Csla.State;
using Moq;
using System.Net.Http;
using Csla.Blazor.WebAssembly.Configuration;
using Csla.Core;
using Csla.Runtime;
using Moq.Protected;
using System.Net;
using Csla.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using Csla.Serialization.Mobile;
using Microsoft.AspNetCore.Components.Authorization;
using NSubstitute;

namespace Csla.Test.State
{
Expand All @@ -27,13 +26,13 @@ public class SessionManagerTests
[TestInitialize]
public void Initialize()
{
var mockServiceProvider = new Mock<IServiceProvider>();
var mockServiceProvider = Substitute.For<IServiceProvider>();

// Mock AuthenticationStateProvider
var mockAuthStateProvider = new Mock<AuthenticationStateProvider>();
var mockAuthStateProvider = Substitute.For<AuthenticationStateProvider>();

// Mock IServiceProvider
mockServiceProvider.Setup(x => x.GetService(typeof(AuthenticationStateProvider))).Returns(mockAuthStateProvider.Object);
mockServiceProvider.GetService(typeof(AuthenticationStateProvider)).Returns(mockAuthStateProvider);

_sessionValue = new SessionMessage
{
Expand All @@ -44,73 +43,59 @@ public void Initialize()
};

// Mock ISerializationFormatter
var mockFormatter = new Mock<ISerializationFormatter>();
mockFormatter.Setup(x => x.Serialize(It.IsAny<Stream>(), It.IsAny<object>()));
mockFormatter.Setup(x => x.Deserialize(It.IsAny<Stream>())).Returns(_sessionValue);
var mockFormatter = Substitute.For<ISerializationFormatter>();
mockFormatter.Serialize(Arg.Any<Stream>(), Arg.Any<object>());
mockFormatter.Deserialize(Arg.Any<Stream>()).Returns(_sessionValue);

// Mock IServiceProvider
mockServiceProvider.Setup(x => x.GetService(typeof(Csla.Serialization.Mobile.MobileFormatter))).Returns(mockFormatter.Object);
mockServiceProvider.GetService(typeof(Csla.Serialization.Mobile.MobileFormatter)).Returns(mockFormatter);

var mockActivator = new Mock<Csla.Server.IDataPortalActivator>();
mockActivator.Setup(x => x.CreateInstance(It.Is<Type>(t => t == typeof(Csla.Serialization.Mobile.MobileFormatter)))).Returns(mockFormatter.Object);
mockActivator.Setup(x => x.InitializeInstance(It.IsAny<object>()));
var mockActivator = Substitute.For<Csla.Server.IDataPortalActivator>();
mockActivator.CreateInstance(Arg.Is<Type>(t => t == typeof(Csla.Serialization.Mobile.MobileFormatter))).Returns(mockFormatter);
mockActivator.InitializeInstance(Arg.Any<object>());

// Mock IServiceProvider
mockServiceProvider.Setup(x => x.GetService(typeof(Csla.Server.IDataPortalActivator))).Returns(mockActivator.Object);
mockServiceProvider.GetService(typeof(Csla.Server.IDataPortalActivator)).Returns(mockActivator);

// Mock IContextManager
var mockContextManager = new Mock<IContextManager>();
mockContextManager.Setup(x => x.IsValid).Returns(true);
var mockContextManager = Substitute.For<IContextManager>();
mockContextManager.IsValid.Returns(true);

// Mock IContextManagerLocal
var mockLocalContextManager = new Mock<IContextManagerLocal>();
var mockLocalContextManager = Substitute.For<IContextManagerLocal>();

// Mock IServiceProvider
mockServiceProvider.Setup(x => x.GetService(typeof(IRuntimeInfo))).Returns(new RuntimeInfo());
mockServiceProvider.GetService(typeof(IRuntimeInfo)).Returns(new RuntimeInfo());

// Mock IEnumerable<IContextManager>
var mockContextManagerList = new List<IContextManager> { mockContextManager.Object };
var mockContextManagerList = new List<IContextManager> { mockContextManager };

// Mock ApplicationContextAccessor
var mockApplicationContextAccessor = new Mock<ApplicationContextAccessor>(mockContextManagerList, mockLocalContextManager.Object, mockServiceProvider.Object);

var _applicationContext = new ApplicationContext(mockApplicationContextAccessor.Object);
var mockApplicationContextAccessor = Substitute.For<ApplicationContextAccessor>(mockContextManagerList, mockLocalContextManager, mockServiceProvider);

var _applicationContext = new ApplicationContext(mockApplicationContextAccessor);

_sessionManager = new SessionManager(_applicationContext, GetHttpClient(_sessionValue, _applicationContext), new BlazorWebAssemblyConfigurationOptions { SyncContextWithServer = true });
}

public class TestHttpMessageHandler(SessionMessage session, ApplicationContext _applicationContext) : HttpMessageHandler
{
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
var response = new HttpResponseMessage()
{
StatusCode = HttpStatusCode.OK,
Content = new StringContent("{\"ResultStatus\":0, \"SessionData\":\"" + Convert.ToBase64String(GetSession(session, _applicationContext)) + "\"}"),
};
return Task.FromResult(response);
}
}
private static HttpClient GetHttpClient(SessionMessage session, ApplicationContext _applicationContext)
{
var handlerMock = new Mock<HttpMessageHandler>(MockBehavior.Strict);
handlerMock
.Protected()
// Setup the PROTECTED method to mock
.Setup<Task<HttpResponseMessage>>(
"SendAsync",
ItExpr.IsAny<HttpRequestMessage>(),
ItExpr.IsAny<CancellationToken>()
)
// prepare the expected response of the mocked http call
.ReturnsAsync((HttpRequestMessage request, CancellationToken cancellationToken) =>
{
if (cancellationToken.IsCancellationRequested)
{
throw new OperationCanceledException(cancellationToken);
}
else
{
return new HttpResponseMessage()
{
StatusCode = HttpStatusCode.OK,
Content = new StringContent("{\"ResultStatus\":0, \"SessionData\":\"" + Convert.ToBase64String(GetSession(session, _applicationContext)) + "\"}"),
};
}
})
.Verifiable();

var handlerMock = new TestHttpMessageHandler(session,_applicationContext);
// use real http client with mocked handler here
var httpClient = new HttpClient(handlerMock.Object)
var httpClient = new HttpClient(handlerMock)
{
BaseAddress = new Uri("http://test.com/"),
};
Expand Down