chore: extract a testcontext that uses an actual telerikrootfragment

This commit is contained in:
radkostanev 2022-04-20 11:00:53 +03:00
Родитель 6cb70c51e2
Коммит d964796519
6 изменённых файлов: 135 добавлений и 8 удалений

Просмотреть файл

@ -1,19 +1,20 @@
using System;
using Bunit;
using Bunit.JSInterop;
using Bunit;
using Microsoft.AspNetCore.Components;
using Microsoft.Extensions.DependencyInjection;
using Telerik.JustMock;
using Microsoft.JSInterop;
using System;
using Telerik.Blazor.Components;
using Telerik.Blazor.Services;
using Microsoft.JSInterop;
using Telerik.JustMock;
namespace Telerik.Blazor.BUnit.JustMock.Common
{
/// <summary>
/// TestContext using a CascadingValue of type <see cref="TelerikRootComponent"/>, rather than the actual implementation.
/// </summary>
public class TelerikTestContext : TestContext
{
private IRenderedComponent<TelerikRootComponent>? rootComponent;
public IRenderedComponent<TelerikRootComponent> RootComponent
=> rootComponent ?? throw new InvalidOperationException("The RootComponent is not available before a component has been rendered with the TestContext.");
@ -27,6 +28,7 @@ namespace Telerik.Blazor.BUnit.JustMock.Common
// make sure JS Interop is available first
Services.AddSingleton(jsRuntimeMock);
// add the Telerik Blazor services like in a regular app
Services.AddTelerikBlazor();
Services.AddSingleton(localizerMock);

Просмотреть файл

@ -0,0 +1,77 @@
using Bunit;
using Microsoft.AspNetCore.Components;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.JSInterop;
using System;
using Telerik.Blazor.Components;
using Telerik.Blazor.Services;
using Telerik.JustMock;
namespace Telerik.Blazor.BUnit.JustMock.Common
{
/// <summary>
/// TestContext using an actual <see cref="TelerikRootComponent"/> that wraps the rendered content from the CUT.
/// Useful when the test depends on a certain logic contained within the RootComponent, such as when testing Dialogs.
/// </summary>
public class TelerikTestContextWithActualRoot : TestContext
{
private IRenderedComponent<TelerikRootComponent>? rootComponent;
private RenderFragment rootFragment;
public IRenderedComponent<TelerikRootComponent> RootComponent
=> rootComponent ?? throw new InvalidOperationException("The RootComponent is not available before a component has been rendered with the TestContext.");
public TelerikTestContextWithActualRoot()
{
// mock the JS Interop service, you cannot use the one coming from the context
var jsRuntimeMock = Mock.Create<IJSRuntime>();
// you can also register a real one for actual localization to test that too
var localizerMock = Mock.Create<ITelerikStringLocalizer>();
// make sure JS Interop is available first
Services.AddSingleton(jsRuntimeMock);
// add the Telerik Blazor services like in a regular app
Services.AddTelerikBlazor();
Services.AddSingleton(localizerMock);
}
public override IRenderedFragment Render(RenderFragment renderFragment)
{
EnsureRootComponent(renderFragment);
return base.Render(rootFragment);
}
public override IRenderedComponent<TComponent> Render<TComponent>(RenderFragment renderFragment)
{
EnsureRootComponent(renderFragment);
return base.Render<TComponent>(rootFragment);
}
public override IRenderedComponent<TComponent> RenderComponent<TComponent>(params ComponentParameter[] parameters)
{
return base.RenderComponent<TComponent>(parameters);
}
public override IRenderedComponent<TComponent> RenderComponent<TComponent>(Action<ComponentParameterCollectionBuilder<TComponent>> parameterBuilder)
{
return base.RenderComponent(parameterBuilder);
}
public void EnsureRootComponent(RenderFragment fragment)
{
if (rootComponent is not null) return;
// Initialize a parameter collection with ChildContent prop, which contains the currently tested
// fragment. This way anything we test will correctly be a descendant of the TelerikRootComponent.
var cpc = new ComponentParameterCollection();
cpc.Add(ComponentParameter.CreateParameter("ChildContent", fragment));
// Save a copy of the root fragment
rootFragment = cpc.ToRenderFragment<TelerikRootComponent>();
// Render the root component and assign it to a field so it can be used when testing
rootComponent = base.Render<TelerikRootComponent>(rootFragment);
}
}
}

Просмотреть файл

@ -0,0 +1,23 @@
using Bunit;
using BUnit_Sample.Pages;
using Telerik.Blazor.BUnit.JustMock.Common;
using Xunit;
namespace Telerik.Blazor.BUnit.JustMock
{
public class DialogPage : TelerikTestContextWithActualRoot
{
[Fact]
public void Dialog_alert_triggered_on_button_click()
{
_ = RenderComponent<Dialog>();
var button = this.RootComponent.Find("button[id=\"dialog-show-button\"]");
button.Click();
Assert.Contains("Something went wrong!", this.RootComponent.Markup);
}
}
}

Просмотреть файл

@ -10,7 +10,7 @@ namespace Telerik.Blazor.BUnit.JustMock
[Fact]
public void Button_in_window_is_rendered()
{
RenderComponent<Window_Button>();
_ = RenderComponent<Window_Button>();
var button = this.RootComponent.Find("button[id=\"window-test-button\"]");
@ -20,7 +20,7 @@ namespace Telerik.Blazor.BUnit.JustMock
[Fact]
public void Button_in_window_click_action()
{
RenderComponent<Window_Button>();
_ = RenderComponent<Window_Button>();
var button = this.RootComponent.Find("button[id=\"window-test-button\"]");

Просмотреть файл

@ -0,0 +1,23 @@
@page "/dialog"
<TelerikButton Id="dialog-show-button" OnClick="@ShowAlert">Show Alert</TelerikButton>
<TelerikButton OnClick="@ShowAlertWithTitle">Show Alert with Custom Title</TelerikButton>
@code {
[CascadingParameter]
public DialogFactory Dialogs { get; set; }
public async Task ShowAlert()
{
await Dialogs.AlertAsync("Something went wrong!");
Console.WriteLine("The user dismissed the alert box.");
}
async Task ShowAlertWithTitle()
{
await Dialogs.AlertAsync("Something went wrong!", "Read this!");
Console.WriteLine("The user dismissed the alert box with the custom title.");
}
}

Просмотреть файл

@ -1,5 +1,7 @@
@page "/button-window-integration"
<p>Some random content</p>
<TelerikWindow Visible="true">
<WindowTitle>
Window