Open martasp opened 4 months ago
I managed to get the TracesViewModel service by adding a hosted service DashboardWebApplication:
services.AddHostedService<DashboardWebApplication>();
Here is the full code snippet:
using System.Net;
using Microsoft.Extensions.DependencyInjection;
using Aspire.Dashboard;
using Aspire.Dashboard.Model;
using Microsoft.Extensions.Logging;
using Microsoft.AspNetCore.Builder;
using System.Reflection;
using Microsoft.Extensions.Hosting;
namespace SamplesIntegrationTests.Works;
public class MyServiceConfigurator
{
public void Configure(IServiceCollection services)
{
}
}
public static class ServiceCollectionExtensions
{
public static object GetService(this IServiceProvider provider, Type serviceType, Type implementationType)
{
if (provider is null)
throw new ArgumentNullException(nameof(provider));
if (serviceType is null)
throw new ArgumentNullException(nameof(serviceType));
if (implementationType is null)
throw new ArgumentNullException(nameof(implementationType));
var service = provider.GetServices(serviceType)
.FirstOrDefault(s => s.GetType() == implementationType);
if (service == null)
throw new InvalidOperationException($"No service for type '{serviceType}' and implementation '{implementationType}' has been registered.");
return service;
}
public static TService GetService<TService>(this IServiceProvider provider, Type implementationType) where TService : class
{
if (provider is null)
throw new ArgumentNullException(nameof(provider));
if (implementationType is null)
throw new ArgumentNullException(nameof(implementationType));
var service = provider.GetServices<TService>()
.FirstOrDefault(s => s.GetType() == implementationType);
if (service == null)
throw new InvalidOperationException($"No service for type '{typeof(TService)}' and implementation '{implementationType}' has been registered.");
return service;
}
}
public static class DashboardWebApplicationExtensions
{
public static IServiceProvider GetAppServices(this DashboardWebApplication dashboardWebApplication)
{
// Use reflection to get the private _app field
FieldInfo appField = typeof(DashboardWebApplication).GetField("_app", BindingFlags.NonPublic | BindingFlags.Instance);
if (appField == null)
{
throw new InvalidOperationException("The DashboardWebApplication class does not contain a private field named '_app'.");
}
// Get the _app instance from the dashboardWebApplication instance
WebApplication appInstance = appField.GetValue(dashboardWebApplication) as WebApplication;
if (appInstance == null)
{
throw new InvalidOperationException("Unable to retrieve the WebApplication instance from the DashboardWebApplication instance.");
}
// Return the IServiceProvider from the WebApplication instance
return appInstance.Services;
}
}
public static class IDistributedApplicationTestingBuilderExtensions
{
public static IServiceCollection AddDashboardWebApplication(this IServiceCollection services)
{
var loggerFactory = LoggerFactory.Create(builder =>
{
builder.AddConsole();
});
var myServiceConfigurator = new MyServiceConfigurator();
var logger = loggerFactory.CreateLogger<DashboardWebApplication>();
services.AddTransient(sp => logger);
services.AddTransient<Action<IServiceCollection>>(sp => myServiceConfigurator.Configure);
services.AddHostedService<DashboardWebApplication>();
return services;
}
public static IServiceProvider GetDashboardWebApplication(this IServiceProvider services)
{
var dashboardWebApplication = (DashboardWebApplication)services.GetService<IHostedService>(typeof(DashboardWebApplication));
var serviceProvider = dashboardWebApplication.GetAppServices();
return serviceProvider;
}
}
public class Works()
{
[Fact]
public async Task EndpointCall_ShouldGenerateDistributedTracesFails()
{
// Arrange
var appHost = await DistributedApplicationTestingBuilder.CreateAsync<Projects.AspireShop_AppHost>();
await using var app = await appHost.BuildAsync();
await app.StartAsync();
// getting aspire TracesViewModel service, but tracesViewModel is null ?
var tracesViewModel = app.Services.GetService<TracesViewModel>();
//how can i get aspire TracesViewModel service?
// Act
var httpClient = app.CreateHttpClient("frontend");
var response = await httpClient.GetAsync("/");
// Assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
Assert.NotEmpty(tracesViewModel.GetTraces().Items);
await app.StopAsync();
}
[Fact]
public async Task EndpointCall_ShouldGenerateDistributedTracesWorks()
{
// Arrange
var appHost = await DistributedApplicationTestingBuilder.CreateAsync<Projects.AspireShop_AppHost>();
appHost.Services.AddDashboardWebApplication();
await using var app = await appHost.BuildAsync();
await app.StartAsync();
var tracesViewModel = app.Services.GetDashboardWebApplication().GetService<TracesViewModel>();
// Act
var httpClient = app.CreateHttpClient("frontend");
var response = await httpClient.GetAsync("/");
// Assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
Assert.NotEmpty(tracesViewModel.GetTraces().Items);
await app.StopAsync();
}
}
Are there any better ways to get traces, and logs for testing?
Adding full poc repo: https://github.com/dotnet/aspire-samples/pull/361
This is a feature request. Ability to collect traces/structured logs/metrics in testing.
When I get the aspire TracesViewModel service from services it's null.
How can I get the aspire TracesViewModel service?