You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
What version of .NET does your existing project use?
.NET 6
What version of .NET are you attempting to target?
.NET 8
Description
After the migration to .NET 8, in order to use SignalR with Azure Functions, it's required to inherit from ServerlessHub. This is no longer unit testable or at least I couldn't find a way to do so.
Here's an example code that I want to unit test.
using DT.Common.Enums.WebSocket;
using DT.Host.Common.Contract.LocalAuthentication;
using DT.Host.SignalRProcessor.Contract;
using Microsoft.Extensions.Logging;
using System;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.SignalRService;
using Microsoft.AspNetCore.SignalR;
using Newtonsoft.Json;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Http;
using FromBodyAttribute = Microsoft.Azure.Functions.Worker.Http.FromBodyAttribute;
using System.Diagnostics.CodeAnalysis;
namespace DT.Host.SignalRProcessor.Functions
{
[SignalRConnection("ConnectionStrings:SignalR")]
[ExcludeFromCodeCoverage]
public class SignalRMessageProcessor : ServerlessHub
{
private const string HubName = "digitaltrust";
private readonly IAuthenticationManager _authenticationManager;
private readonly ILogger<SignalRMessageProcessor> _logger;
public SignalRMessageProcessor(
IServiceProvider serviceProvider,
IAuthenticationManager authenticationManager,
ILogger<SignalRMessageProcessor> logger) : base(serviceProvider)
{
_authenticationManager = authenticationManager;
_logger = logger;
}
[Function("negotiate")]
public async Task<IActionResult> Negotiate(
[HttpTrigger("get", Route = "negotiate/{userId}")] HttpRequest req,
string userId)
{
var statusCode = Authenticate(req);
if (statusCode != StatusCodes.Status200OK)
{
return new StatusCodeResult(statusCode);
}
_logger.LogInformation($"userId: {userId}; Negotiate Function triggered");
var negotiateResponse = await NegotiateAsync(new() { UserId = userId });
var response = JsonConvert.DeserializeObject<SignalRConnectionInfo>(negotiateResponse.ToString());
return new OkObjectResult(response);
}
private int Authenticate(HttpRequest req)
{
req.Headers.TryGetValue("Authorization", out var authHeader);
if (authHeader.FirstOrDefault() is null)
{
return StatusCodes.Status403Forbidden;
}
var token = authHeader.First().Trim();
if (token.StartsWith("basic", StringComparison.OrdinalIgnoreCase))
{
try
{
_authenticationManager.Authenticate(token);
return StatusCodes.Status200OK;
}
catch (UnauthorizedAccessException)
{
return StatusCodes.Status401Unauthorized;
}
}
return StatusCodes.Status401Unauthorized;
}
}
Any guidance on this is appreciated. I tried mocking IServiceProvider with no luck.
Project configuration and dependencies
No response
Link to a repository that reproduces the issue
No response
The text was updated successfully, but these errors were encountered:
I don't think I follow your suggestion, the code you provided is injecting the ServiceHubContext but we're really inheriting from the ServerlessHub class.
Is your suggestion to change my production code to include the constructor you posted only for testing purposes?
Is your suggestion to change my production code to include the constructor you posted only for testing purposes?
Yes. This is a common practice that we use a different constructor for testing. You may find many examples in other .NET codes. As the main purpose of IServiceProvider parameter is to provide a ServiceHubContext instance to the serverless hub, it nearly has the same effect to just replace it with a mocked ServiceHubContext in your testing.
What version of .NET does your existing project use?
.NET 6
What version of .NET are you attempting to target?
.NET 8
Description
After the migration to .NET 8, in order to use SignalR with Azure Functions, it's required to inherit from ServerlessHub. This is no longer unit testable or at least I couldn't find a way to do so.
Here's an example code that I want to unit test.
Any guidance on this is appreciated. I tried mocking IServiceProvider with no luck.
Project configuration and dependencies
No response
Link to a repository that reproduces the issue
No response
The text was updated successfully, but these errors were encountered: