Skip to content

Commit

Permalink
Revert "fix: Change all bUnit services registration from singleton to…
Browse files Browse the repository at this point in the history
… scoped"

This reverts commit c34880d.

# Conflicts:
#	CHANGELOG.md
  • Loading branch information
egil committed Jul 13, 2023
1 parent 4353f88 commit fd85b8d
Show file tree
Hide file tree
Showing 10 changed files with 45 additions and 60 deletions.
4 changes: 0 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,6 @@ All notable changes to **bUnit** will be documented in this file. The project ad

- Update bunit templates to support the target framework version of the project. By [@linkdotnet](https://github.com/linkdotnet).

### Changed

- Change all bUnit services registration from singleton to scoped. By [@egil](https://github.com/egil). Closes https://github.com/bUnit-dev/bUnit/issues/1138.

## [1.21.9] - 2023-07-02

### Fixed
Expand Down
6 changes: 3 additions & 3 deletions benchmark/bunit.benchmarks/BenchmarkBase.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Attributes;
using Bunit.Rendering;
using Microsoft.AspNetCore.Components;
using Microsoft.Extensions.DependencyInjection;
Expand Down Expand Up @@ -42,6 +42,6 @@ protected virtual void InternalCleanup()

protected virtual void RegisterServices(IServiceCollection serviceCollection)
{
services.AddScoped<BunitHtmlParser>();
services.AddSingleton<BunitHtmlParser>();
}
}
}
2 changes: 1 addition & 1 deletion src/bunit.core/TestContextBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ protected TestContextBase()
{
Services = new TestServiceProvider();
#if NET5_0_OR_GREATER
Services.AddScoped<ComponentFactoryCollection>(_ => ComponentFactories);
Services.AddSingleton<ComponentFactoryCollection>(_ => ComponentFactories);
#endif
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ public static FakePersistentComponentState AddFakePersistentComponentState(this
if (testContext is null)
throw new ArgumentNullException(nameof(testContext));

testContext.Services.AddScoped<ComponentStatePersistenceManager>();
testContext.Services.AddScoped<PersistentComponentState>(s => s.GetRequiredService<ComponentStatePersistenceManager>().State);
testContext.Services.AddSingleton<ComponentStatePersistenceManager>();
testContext.Services.AddSingleton<PersistentComponentState>(s => s.GetRequiredService<ComponentStatePersistenceManager>().State);
return new FakePersistentComponentState(testContext.Services);
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/bunit.core/TestServiceProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ public object GetService(Type serviceType)
{
if (serviceProvider is null)
{
serviceCollection.AddScoped<TestServiceProvider>(_ => this);
serviceCollection.AddSingleton<TestServiceProvider>(this);
rootServiceProvider = serviceCollection.BuildServiceProvider(options);
serviceScope = rootServiceProvider.CreateScope();
serviceProvider = serviceScope.ServiceProvider;
Expand Down
2 changes: 1 addition & 1 deletion src/bunit.web.testcomponents/Xunit.Sdk/RazorTestInvoker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,6 @@ protected override object CallTestMethod(object testClassInstance)

private void RegisterXunitHelpersInTest(RazorTestBase test)
{
test.Services.AddScoped<ITestOutputHelper>(_ => testOutputHelperFactory());
test.Services.AddSingleton<ITestOutputHelper>(_ => testOutputHelperFactory());
}
}
38 changes: 19 additions & 19 deletions src/bunit.web/Extensions/TestServiceProviderExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,37 +28,37 @@ public static IServiceCollection AddDefaultTestContextServices(this IServiceColl

// Placeholders and defaults for common Blazor services
services.AddLogging();
services.AddScoped<AuthenticationStateProvider, PlaceholderAuthenticationStateProvider>();
services.AddScoped<IAuthorizationService, PlaceholderAuthorizationService>();
services.AddScoped<HttpClient, PlaceholderHttpClient>();
services.AddScoped<IStringLocalizer, PlaceholderStringLocalization>();
services.AddSingleton<AuthenticationStateProvider, PlaceholderAuthenticationStateProvider>();
services.AddSingleton<IAuthorizationService, PlaceholderAuthorizationService>();
services.AddSingleton<HttpClient, PlaceholderHttpClient>();
services.AddSingleton<IStringLocalizer, PlaceholderStringLocalization>();

// bUnits fake JSInterop
services.AddScoped<IJSRuntime>(_ => jsInterop.JSRuntime);
services.AddSingleton<IJSRuntime>(jsInterop.JSRuntime);

// bUnits fake Navigation Manager
services.AddScoped<FakeNavigationManager>();
services.AddScoped<NavigationManager>(s => s.GetRequiredService<FakeNavigationManager>());
services.AddScoped<INavigationInterception, FakeNavigationInterception>();
services.AddSingleton<FakeNavigationManager>();
services.AddSingleton<NavigationManager>(s => s.GetRequiredService<FakeNavigationManager>());
services.AddSingleton<INavigationInterception, FakeNavigationInterception>();

// bUnits fake WebAssemblyHostEnvironment
services.AddScoped<FakeWebAssemblyHostEnvironment>();
services.AddScoped<IWebAssemblyHostEnvironment>(s => s.GetRequiredService<FakeWebAssemblyHostEnvironment>());
services.AddSingleton<FakeWebAssemblyHostEnvironment>();
services.AddSingleton<IWebAssemblyHostEnvironment>(s => s.GetRequiredService<FakeWebAssemblyHostEnvironment>());

// bUnit specific services
services.AddScoped<TestContextBase>(_ => testContext);
services.AddScoped<WebTestRenderer>();
services.AddScoped<TestRenderer>(s => s.GetRequiredService<WebTestRenderer>());
services.AddScoped<Renderer>(s => s.GetRequiredService<WebTestRenderer>());
services.AddScoped<ITestRenderer>(s => s.GetRequiredService<WebTestRenderer>());
services.AddScoped<HtmlComparer>();
services.AddScoped<BunitHtmlParser>();
services.AddScoped<IRenderedComponentActivator, RenderedComponentActivator>();
services.AddSingleton<TestContextBase>(testContext);
services.AddSingleton<WebTestRenderer>();
services.AddSingleton<TestRenderer>(s => s.GetRequiredService<WebTestRenderer>());
services.AddSingleton<Renderer>(s => s.GetRequiredService<WebTestRenderer>());
services.AddSingleton<ITestRenderer>(s => s.GetRequiredService<WebTestRenderer>());
services.AddSingleton<HtmlComparer>();
services.AddSingleton<BunitHtmlParser>();
services.AddSingleton<IRenderedComponentActivator, RenderedComponentActivator>();

services.AddMemoryCache();

#if NET6_0_OR_GREATER
services.AddScoped<IErrorBoundaryLogger, BunitErrorBoundaryLogger>();
services.AddSingleton<IErrorBoundaryLogger, BunitErrorBoundaryLogger>();
#endif
return services;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ public static TestAuthorizationContext AddTestAuthorization(this TestContextBase
throw new ArgumentNullException(nameof(context));

context.RenderTree.TryAdd<CascadingAuthenticationState>();
context.Services.AddScoped<FakeSignOutSessionStateManager>();
context.Services.AddSingleton<FakeSignOutSessionStateManager>();
#pragma warning disable CS0618
context.Services.AddScoped<SignOutSessionStateManager>(s => s.GetRequiredService<FakeSignOutSessionStateManager>());
context.Services.AddSingleton<SignOutSessionStateManager>(s => s.GetRequiredService<FakeSignOutSessionStateManager>());
#pragma warning restore CS0618
var authCtx = new TestAuthorizationContext();
authCtx.SetNotAuthorized();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,19 +56,17 @@ public class TestAuthorizationContext
/// <param name="services">Service provider to use.</param>
public void RegisterAuthorizationServices(IServiceCollection services)
{
services.AddScoped<IAuthorizationService>(_ => authService);
services.AddScoped<IAuthorizationPolicyProvider>(_ => policyProvider);
services.AddScoped<AuthenticationStateProvider>(_ => authProvider);
services.AddSingleton<IAuthorizationService>(authService);
services.AddSingleton<IAuthorizationPolicyProvider>(policyProvider);
services.AddSingleton<AuthenticationStateProvider>(authProvider);
}

/// <summary>
/// Authenticates the user with specified name and authorization state.
/// </summary>
/// <param name="userName">User name for the principal identity.</param>
/// <param name="state">Authorization state.</param>
public TestAuthorizationContext SetAuthorized(
string userName,
AuthorizationState state = AuthorizationState.Authorized)
public TestAuthorizationContext SetAuthorized(string userName, AuthorizationState state = AuthorizationState.Authorized)
{
IsAuthenticated = true;
UserName = userName;
Expand Down
33 changes: 12 additions & 21 deletions tests/bunit.core.tests/Rendering/BunitComponentActivatorTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,49 +6,40 @@ namespace Bunit.Rendering;

public class BunitComponentActivatorTest : TestContext
{
public static TheoryData<Action<IServiceCollection, IComponentActivator>> CustomActivatorRegistrations { get; } = new()
{
static (services, activator) => services.AddSingleton(activator),
static (services, activator) => services.AddScoped(_ => activator),
static (services, activator) => services.AddTransient(_ => activator),
};

[Fact(DisplayName = "Default bUnit activator")]
[Fact(DisplayName = "Default activator")]
public void Test001()
{
var activator = new CustomComponentActivator();
Services.AddSingleton<IComponentActivator>(activator);

var cut = RenderComponent<Simple1>();

cut.Instance.ShouldBeOfType<Simple1>();
}

[Theory(DisplayName = "Custom IComponentActivator registered in Services")]
[MemberData(nameof(CustomActivatorRegistrations))]
public void Test002(Action<IServiceCollection, IComponentActivator> registerCustomActivator)
[Fact(DisplayName = "Custom singleton IComponentActivator registered in Services")]
public void Test002()
{
var activator = new CustomComponentActivator();
registerCustomActivator(Services, activator);
Services.AddSingleton<IComponentActivator>(activator);

RenderComponent<Simple1>();

activator
.RequestedComponentTypes
activator.RequestedComponentTypes
.ShouldHaveSingleItem()
.ShouldBe(typeof(Simple1));
}

[Theory(DisplayName = "Custom singleton IComponentActivator registered in Services with ComponentFactories in use")]
[MemberData(nameof(CustomActivatorRegistrations))]
public void Test003(Action<IServiceCollection, IComponentActivator> registerCustomActivator)
[Fact(DisplayName = "Custom singleton IComponentActivator registered in Services with ComponentFactories in use")]
public void Test003()
{
var activator = new CustomComponentActivator();
registerCustomActivator(Services, activator);

Services.AddSingleton<IComponentActivator>(activator);
ComponentFactories.AddStub<ClickCounter>();

var cut = RenderComponent<Wrapper>(ps => ps.AddChildContent<ClickCounter>());

activator
.RequestedComponentTypes
activator.RequestedComponentTypes
.ShouldHaveSingleItem()
.ShouldBe(typeof(Wrapper));
cut.HasComponent<ClickCounter>().ShouldBeFalse();
Expand Down

0 comments on commit fd85b8d

Please sign in to comment.