Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
41 changes: 40 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,46 @@ List of new features.

NOTE, a better approach is to use the `WaitForState` or `WaitForAssertion` methods, which now also throws unhandled exceptions. Using them, you do not need to set up a wait timeout explicitly.

By [@egil](https://github.com/egil) in [#310](https://github.com/egil/bUnit/issues/344).
By [@egil](https://github.com/egil) in [#344](https://github.com/egil/bUnit/issues/344).

- Added a simple fake navigation manager, which is registered by default in bUnit's service provider. When the fake navigation manager's `NavigateTo` method is called, it does two things:

1. Set the `Uri` property to the URI passed to the `NavigateTo` method (with the URI normalized to an absolute URI).
2. Raise the `LocationChanged` event with the URI passed to the `NavigateTo` method.

Lets look at an example: To verify that the `<GoesToFooOnInit>` component below calls the `NavigationManager.NavigateTo` method with the expected value, do the following:

`<GoesToFooOnInit>` component:

```cshtml
@inject NavigationManager NavMan
@code {
protected override void OnInitialized()
{
NavMan.NavigateTo("foo");
}
}
```

Test code:

```csharp
// Arrange
using var ctx = new TestContext();
var navMan = ctx.Services.GetRequiredService<NavigationManager>();

// Act
var cut = ctx.RenderComponent<GoesToFooOnInit>();

// Assert
Assert.Equal($"{navMan.BaseUri}foo", navMan.Uri);
```

Since the `foo` input argument is normalized to an absolute URI, we have to do the same normalization in our assertion.

The fake navigation manager's `BaseUri` is set to `http://localhost/`, but it is not recommended to use that URL directly in your code. Instead create an assertion by getting that value from the `BaseUri` property, like shown in the example above.

By [@egil](https://github.com/egil) in [#345](https://github.com/egil/bUnit/pull/345).

### Changed
List of changes in existing functionality.
Expand Down
4 changes: 3 additions & 1 deletion src/bunit.web/Extensions/TestServiceProviderExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,15 @@ public static IServiceCollection AddDefaultTestContextServices(this IServiceColl
services.AddSingleton<ILoggerFactory>(NullLoggerFactory.Instance);
services.AddSingleton<AuthenticationStateProvider, PlaceholderAuthenticationStateProvider>();
services.AddSingleton<IAuthorizationService, PlaceholderAuthorizationService>();
services.AddSingleton<NavigationManager, PlaceholderNavigationManager>();
services.AddSingleton<HttpClient, PlaceholderHttpClient>();
services.AddSingleton<IStringLocalizer, PlaceholderStringLocalization>();

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

// bUnits fake Navigation Manager
services.AddSingleton<NavigationManager, FakeNavigationManager>();

// bUnit specific services
services.AddSingleton<TestContextBase>(testContext);
services.AddSingleton<ITestRenderer, WebTestRenderer>();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using System;
using System.Diagnostics.CodeAnalysis;
using Bunit.Rendering;
using Microsoft.AspNetCore.Components;

namespace Bunit.TestDoubles
{
/// <summary>
/// Represents a fake <see cref="NavigationManager"/> that captures calls to
/// <see cref="NavigationManager.NavigateTo(string, bool)"/> for testing purposes.
/// </summary>
public sealed class FakeNavigationManager : NavigationManager
{
private readonly ITestRenderer renderer;

/// <summary>
/// Initializes a new instance of the <see cref="FakeNavigationManager"/> class.
/// </summary>
[SuppressMessage("Minor Code Smell", "S1075:URIs should not be hardcoded", Justification = "By design. Fake navigation manager defaults to local host as base URI.")]
public FakeNavigationManager(ITestRenderer renderer)
{
this.renderer = renderer ?? throw new ArgumentNullException(nameof(renderer));
Initialize("http://localhost/", "http://localhost/");
}

/// <inheritdoc/>
protected override void NavigateToCore(string uri, bool forceLoad)
{
Uri = ToAbsoluteUri(uri).ToString();

renderer.Dispatcher.InvokeAsync(
() => NotifyLocationChanged(isInterceptedLink: false));
}
}
}

This file was deleted.

This file was deleted.

Loading