-
Hi, I am new user, who currently has a test that initialises private void InitialisePageDependencies()
{
// Web Application Server, copy dependencies across
var hubProxyFactory = Server.Services.GetRequiredService<IHubProxyFactory>();
var loggerDetectionConverter = Server.Services.GetRequiredService<ILogger<MotionDetectionConverter>>();
var loggerIndexPage = Server.Services.GetRequiredService<ILogger<WebApp.Pages.Index>>();
var loggerInfoConverter = Server.Services.GetRequiredService<ILogger<MotionInfoConverter>>();
var loggerJsonVisitor = Server.Services.GetRequiredService<ILogger<JsonVisitor>>();
var loggerRepository = Server.Services.GetRequiredService<ILogger<MotionDetectionRepository>>();
var navManager = Server.Services.GetRequiredService<NavigationManager>();
var repository = Server.Services.GetRequiredService<IMotionDetectionRepository>();
// Initialise TestContext services
IndexPage.Services.AddSingleton(typeof(IHubProxyFactory), hubProxyFactory);
IndexPage.Services.AddScoped<ILogger<MotionDetectionConverter>>(sp => loggerDetectionConverter);
IndexPage.Services.AddScoped<ILogger<WebApp.Pages.Index>>(sp => loggerIndexPage);
IndexPage.Services.AddScoped<ILogger<MotionInfoConverter>>(sp => loggerInfoConverter);
IndexPage.Services.AddScoped<ILogger<JsonVisitor>>(sp => loggerJsonVisitor);
IndexPage.Services.AddScoped<ILogger<IMotionDetectionRepository>>(sp => loggerRepository);
IndexPage.Services.AddScoped<MockNavigationManager>(sp => new MockNavigationManager());
IndexPage.Services.AddScoped<IMotionDetectionRepository>(sp => repository);
} The server is ASP.NET Core 3.1 with Autofac container. Am I doing this correctly or is there a quicker way? |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 9 replies
-
Hi @dcs3spp Welcome to the community. I am not sure what you are trying to do, but normally bunit doesn't run in a Blazor server or Blazor Wasm. You run it within e.g. xunit or nunit. If you want to learn how to setup bunit, i recommend checking out the docs here: https://bunit.egilhansen.com/docs/getting-started/index.html |
Beta Was this translation helpful? Give feedback.
-
Hi @egil, thanks :) Apologies.....posting full code of xUnit fixture...trying to initialise services of TestContext with services from self host (IHost) or WebApplicationFactory for the pruposes of functional test. The method is used to copy across necessary dependencies from the host into the "Blazor Server" page for functional testing in xUnit, rather than have two instances/sets of sevices on the Blazor server page and self host test server (IHost).... Is the method in original post the correct way of doing this or is there a quicker way? Currently, have to resolve each individual dependency across. Is there a way to copy all services across in one go? using System;
using System.Threading.Tasks;
using Autofac.Extensions.DependencyInjection;
using Bunit;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using MQTTnet.Extensions.ManagedClient;
using Xunit;
using WebApp.Mqtt.Contracts;
namespace WebApp.FunctionalTests
{
/// <summary>
/// Work in progress to provide an in process host or WebApplicationFactory test server. So far using in process host
/// Using for full functional test to test data is displayed on front end when something is posted on Kafka back-end
/// Build a self host ASP.NET Core instance
/// uSse xunit IAsyncLifeTime to start and stop it in test fixtures
/// </summary>
/// <remarks>
/// NavigationManager, we need to get the baseUrl sorted
/// This fixture, we need to initialise and compile so that it contains the IndexPage services and disposed
/// </remarks>
public class SelfHostedServer : IAsyncLifetime, IDisposable
{
public IManagedMqttClient MqttClient { get; private set; }
public IHost Server { get; private set; }
public ConfigMetaData ConfigMetaData { get; }
public TestContext IndexPage { get; } // TODO : dispose
#region Fixture setup
public SelfHostedServer()
{
// load secrets from .env file, or load them from env vars if running in a docker container
EnvironmentHelper.LoadEnvironmentVariables();
// based upon the ASPNETCORE_ENVIRONMENT get the config meta data
ConfigMetaData = SettingsFile.GetConfigMetaData();
// build the host instance
Server = new HostBuilder()
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
.ConfigureLogging(logging =>
{
logging.ClearProviders();
logging.AddConsole();
logging.AddFilter("Microsoft.AspNetCore.SignalR", LogLevel.Information);
})
.ConfigureWebHost(webBuilder =>
{
webBuilder.ConfigureAppConfiguration((context, cb) =>
{
cb.AddJsonFile(ConfigMetaData.SettingsFile, optional: false)
.AddEnvironmentVariables();
})
.UseStartup<Startup>()
.UseKestrel()
.UseUrls("http://127.0.0.1:5000"); // TODO: workout how to make dynamic and reference with NavigationManager
}).Build();
}
#endregion
/// <summary>
/// This method is used to copy across necessary dependencies from the host into the "Blazor Server" page
/// for functional testing, rather than have two sets of sevices....
/// </summary>
private void InitialisePageDependencies()
{
var hubProxyFactory = Server.Services.GetRequiredService<IHubProxyFactory>();
var loggerDetectionConverter = Server.Services.GetRequiredService<ILogger<MotionDetectionConverter>>();
var loggerIndexPage = Server.Services.GetRequiredService<ILogger<WebApp.Pages.Index>>();
var loggerInfoConverter = Server.Services.GetRequiredService<ILogger<MotionInfoConverter>>();
var loggerJsonVisitor = Server.Services.GetRequiredService<ILogger<JsonVisitor>>();
var loggerRepository = Server.Services.GetRequiredService<ILogger<MotionDetectionRepository>>();
var navManager = Server.Services.GetRequiredService<NavigationManager>();
var repository = Server.Services.GetRequiredService<IMotionDetectionRepository>();
IndexPage.Services.AddSingleton(typeof(IHubProxyFactory), hubProxyFactory);
IndexPage.Services.AddScoped<ILogger<MotionDetectionConverter>>(sp => loggerDetectionConverter);
IndexPage.Services.AddScoped<ILogger<WebApp.Pages.Index>>(sp => loggerIndexPage);
IndexPage.Services.AddScoped<ILogger<MotionInfoConverter>>(sp => loggerInfoConverter);
IndexPage.Services.AddScoped<ILogger<JsonVisitor>>(sp => loggerJsonVisitor);
IndexPage.Services.AddScoped<ILogger<IMotionDetectionRepository>>(sp => loggerRepository);
IndexPage.Services.AddScoped<MockNavigationManager>(sp => new MockNavigationManager());
IndexPage.Services.AddScoped<IMotionDetectionRepository>(sp => repository);
}
#region Implement ILifetimeAsync, Xunit equivalent of IDisposeAsync, until upcoming version of Xunit provides IDisposeAsync
public async Task InitializeAsync()
{
await Server?.InitAsync();
await Server.StartAsync();
MqttClient = (Server.Services.GetService(typeof(IMqttService)) as IMqttService).Client;
InitialisePageDependencies();
}
public async Task DisposeAsync()
{
await Server?.StopAsync();
Dispose();
}
#endregion
#region Dispose
public void Dispose()
{
Dispose(disposing: true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
Server?.Dispose();
}
Server = null;
}
#endregion
}
} |
Beta Was this translation helpful? Give feedback.
-
Cheers @egil thanks for your feedback and patience, that has indeed helped, appreciated :) Yep, will be happy to try and pop back with a write up in show and tell section. Needs some refining/refactoring beforehand...introducing abstract classes for Server and BlazorServerPage, getting the NavigationManager working based on baseUrl from generic host etc. However, it is now allowing me to run and produce a single functional test from back-end to front-end Blazor server page.
Yep agree, the point you have raised here is especially important with this approach for full stack testing with Blazor Server pages. I will also have to try and experiment a little further with getting the NavigationManager dependency hooked up correctly. From what I have read in documentation, the approach for unit tests is to create a mock class derived from the abstract class |
Beta Was this translation helpful? Give feedback.
Cheers @egil thanks for your feedback and patience, that has indeed helped, appreciated :)
Yep, will be happy to try and pop back with a write up in show and tell section.
Needs some refining/refactoring beforehand...introducing abstract classes for Server and BlazorServerPage, getting the NavigationManager working based on baseUrl from generic host etc. However, it is now allowing me to run and produce a single functional test from back-end to front-end Blazor server page.
Yep agree, the point you have raised…