All notable changes to bUnit will be documented in this file. The project adheres to Semantic Versioning.
1.9.8 - 2022-06-07
WaitForAssertionmethod is now marked as an assertion method with the[AssertionMethod]attribute. This makes certain analyzers like SonarSource's Tests should include assertions happy. By @egil.
-
A race condition existed between
WaitForState/WaitForAssertionandFindComponents, if the first used the latter. Reported by @rmihael, @SviatoslavK, and @RaphaelMarcouxCTRL. Fixed by @egil and @linkdotnet. -
Triggering of event handlers now runs entirely inside the renderers synchronization context, avoiding race condition between elements in the DOM tree being updated by the renderer and the event triggering logic traversing the DOM tree to find event handlers to trigger. Reported by @FlukeFan. Fixed by @egil.
1.8.15 - 2022-05-19
- Added test helpers that make it much easier to pass files to the
InputFilecomponent. Learn more in the documentation. By @egil and @linkdotnet.
HtmlizerusesStringBuilderinstead ofList<string>to reduce allocations and improve render speed. By @linkdotnet.
-
TestServiceProvidernow implementsIAsyncDisposable. This meansTestContext.Dispose()now calls the async disposable method as well as the non-async version on the service provider. It does however not block or await the task returned, since that can lead to deadlocks.To await the disposal of async services registered in the
TestContext.Servicescontainer, do the following:- Create a new type that derives from
TestContextand which implementIAsyncDisposable. - In the
DisposeAsync()method, callServices.DisposeAsync(). - Override the
Disposeand have it only callServices.Dispose().
- Create a new type that derives from
1.7.7 - 2022-04-29
-
Added method
SetAuthenticationTypetoTestAuthorizationContextto allow for custom authentication type checks. By @TimPurdum. -
Added
DisposeComponentstoTestContextBase. It will dispose and remove all components rendered by theTestContextBase. By @linkdotnet. -
Added .NET 7 as a target framework for bUnit. By @linkdotnet.
-
Fixed step by step guide for building and viewing the documentation locally. By @linkdotnet.
-
FakeNavigationManager.NavigateTocould lead to exceptions when navigating to external url's. Reported by @TDroogers. Fixed by @linkdotnet.
1.6.4 - 2022-02-22
A quick minor release that primiarily fixes a regression in 1.5.12.
ClickAsynccould lead to bubbling exceptions fromGetDispatchEventTaskseven though they should be handled. Reported by @aguacongas. Fixed by @linkdotnet.- Added more non bubbling events to bUnit so it behaves closer to the HTML specification. @linkdotnet.
1.5.12 - 2022-02-15
This first release of 2022 includes one fix and four additions. A huge thank you to Steven Giesel (@linkdotnet) and Denis Ekart (@denisekart) for their contributions to this release.
Also a big shout out to bUnit's sponsors who helped make this release happen.
The higher tier sponsors are:
Other sponsors are:
- Hassan Rezk Habib (@hassanhabib)
- Jonny Larsson (@Garderoben)
- Domn Werner (@domn1995)
- Mladen Macanović (@stsrki)
- @ChristopheDEBOVE
- Steven Giesel (@linkdotnet)
- Added
FakeSignOutSessionStateManagetype in Blazor, that makes it easy to test components that use theSignOutSessionStateManagetype. By @linkdotnet. - Added a validation to
AddChildContentmethod inComponentParameterCollectionBuilderthat will throw an exception if the component'sChildContentis a generic type. By @denisekart. - Added more optional arguments for
ClickandDoubleClickextensions which were introduced in .NET 5 and .NET 6. By @linkdotnet. - Added template support for
NunitandMSTestunit test frameworks. By @denisekart.
- Changed
GetDispatchEventTasksfor bubbling events such that handled exceptions are not rethrown later from theWaitFor...helpers methods. Reported by @AndrewStrickland. Fixed by @linkdotnet
1.4.15 - 2021-12-18
This release reintroduces Stub<TComponent> and related back into the main library, so the "preview" library bunit.web.mock is already obsolete.
A big shout out to bUnit's sponsors who helped make this release happen.
The higher tier sponsors are:
Other sponsors are:
- Hassan Rezk Habib (@hassanhabib)
- Jonny Larsson (@Garderoben)
- Domn Werner (@domn1995)
- Mladen Macanović (@stsrki)
- @ChristopheDEBOVE
- Add
ComponentFactoriesextensions method that makes it easy to register an instance of a replacement component. By @egil. - Add ability to pass
ServiceProviderOptionstoTestServiceProviderthrough property to allow users to customize the service provider. By @rodolfograve.
- Changed
SetParametersAndRendersuch that it rethrows any exceptions thrown by the component under testsSetParametersAsyncmethod. Thanks to @bonsall for reporting the issue. Fixed by @egil. onclickon a button inside a form will raise theonsubmitevent for the form itself. Reported by [@egil]. Fixed by @linkdotnet.- Only forms are allowed to have a
onsubmitevent handler. Whenonsubmitis invoked from a non-form element results in an exception. Fixed by @linkdotnet.
1.3.42 - 2021-11-09
This release includes support for .NET 6, with support for all new features in Blazor with that release. There are also a number of additions and fixes, all listed below.
Big shout out to bUnit's sponsors who helped make this release happen.
The higher tier sponsors are:
Other sponsors are:
- Hassan Rezk Habib (@hassanhabib)
- Jonny Larsson (@Garderoben)
- Domn Werner (@domn1995)
- Mladen Macanović (@stsrki)
- @ChristopheDEBOVE
List of added functionality in this release.
-
Added support for writing tests of components that use the
<FocusOnNavigate>component included in .NET 6. This includes an assertion helper methodVerifyFocusOnNavigateInvokeon bUnit'sJSInteropthat allow you to verify that<FocusOnNavigate>has set focus on an element during render. For example, to verify thath1selector was used to pick an element to focus on, do:// <App /> component uses <FocusOnNavigate> var cut = RenderComponent<App>(); // Verifies that <FocusOnNavigate> called it's JavaScript function var invocation = JSInterop.VerifyFocusOnNavigateInvoke(); // Verify that the invocation of <FocusOnNavigate> JavaScript function included the "h1" as the selector Assert.Equal("h1", invocation.Arguments[0]);
By @egil.
-
Added fake version of the
PersistentComponentStatetype in Blazor that makes it possible to test components that use the type. By @egil. -
Added
TriggerEventmethod to make it easier to trigger custom events. By @egil. -
Added
Historycapture in theFakeNavigationManager. By @egil. -
Added new bUnit component mocking library, available via NuGet as
bunit.web.mock. It is currently in preview and the features/APIs of it will change! -
Added
WaitForElementandWaitForElementsmethods. These makes it possible to wait for one or more elements to appear in the DOM before continuing a test, similar to howWaitForAssertionallows you to wait for an assertion to pass, orWaitForStateallows you to wait for a predicate to pass. By @egil.
- Added automatic conversion of values (types) passed to
Change()andInput()event trigger methods. This means that e.g. aDateTimepassed toChange()is automatically converted to a string format that Blazor expects. By @egil.
-
The
ClickandDoubleClickextension methods now set theMouseEventArgs.Detailproperty to1and2respectively by default, unless the user specifies something else. This makes the methods more correctly emulate how Blazor reports single or double clicks on an element in the browser. Thanks to @David-Moreira for the help troubleshooting this issue. By @egil. -
FocusAsync()method handler onElementReferenceand<FocusOnNavigate>js handler return completedTask. By @anddrzejb. -
Fixes handling of disposed event handlers of bubbling events. See issue #518 for details. Thanks to @David-Moreira for helping debug this issue.
-
Async event trigger methods are not public. In most circumstances you do not need to use them, but if you have a scenario where you want to check that something has not happened after an event handler was triggered, then you can use the async methods and await them to know when they are completed. See #552 for details. By @egil.
1.2.49 - 2021-08-09
List of added functionality in this release.
-
Added more extensions methods to
MarkupMatchesAssertExtensionsto allow asserting withMarkupMatchesonIEnumerableandIElement. By @jgoday. -
Added
BunitErrorBoundaryLoggerimplementation ofIErrorBoundaryLogger(needed for Blazor's ErrorBoundary component in .NET 6.0). By @jgoday. -
Added
ComponentFactoriesproperty to theTestContextBasetype. TheComponentFactoriesproperty is aComponentFactoryCollectiontype that containsIComponentFactorytypes. These are used by bUnits component activator, whenever a component is created during testing. If no component factories is added to the collection, the standard component activator mechanism from Blazor is used. This feature makes it possible to control what components are created normally during a test, and which should be e.g. replaced by a test dummy. More info is available in issue #388.
Learn more about this feature on the Controlling component instantiation page. -
Added
HasComponent<TComponent>()toIRenderedFragement. Use it to check if the rendered fragment contains a component of typeTComponent. Added by @egil. -
Added
AddStubandAddextension methods toComponentFactoriesthat makes it easy to configure bUnit to replace components in the render tree with stubs. Both methods have overloads that allow for fine grained selection of component types to "double" during testing. Added by @egil in #400.
List of changes in this release.
-
Updated AngleSharp and related libraries to 0.16.0. NOTE, the new version of AngleSharp includes nullable annotations, which might affect how your code compiles, if you have nullable checking enabled in your test project. By @egil.
-
Updated .NET 6 dependencies to preview 5. By @egil.
List of fixes in this release.
-
Fixed JSInterop error message when trying to import an unconfigured module. By @jgoday in #425.
-
Fixed issue where a registered fall-back service provider was not made available to resolve service dependencies of components under test. Thanks to @dady8889 for the reporting the issue.
-
Fixed handling of escaped uri's in FakeNavigationManager. By @linkdotnet in #460.
-
Captured error message from event dispatcher in renderer that would previously be hidden from the user. Related to issue #399.
1.1.5 - 2021-04-30
-
All bUnit assemblies is now strong named signed.
-
Added .NET 6 (preview 3) as a target framework for bUnit, bUnit.core and bUnit.web.
-
Changed bunit.template such that created projects only reference the bUnit package. Bumped other referenced packages to latest version.
-
Changed TestServiceProvider to validate scopes of registered services, such that it behaves like the service provider (default IoC container) in Blazor.
The following section list all changes since preview 02.
List of changes in existing functionality.
-
BREAKING CHANGE: Writing tests using the test components
<Fixture>and<SnapshotTest>components inside .razor files has been moved to its own library,bunit.web.testcomponents. This was done for several reasons:- The feature has been experimental since it was introduced, and it was introduced get a more natural way of specifying the component under test and any related markup used by test.
- The feature is only supported with xUnit.
- There are some issues related to the
SourceFileFinderlibrary, which is used to discover the test components. - A better way of writing tests in .razor files has been added to bUnit, using "inline render fragments". This method works with all general purpose test frameworks, e.g. MSTest, NUnit, and xUnit, is more flexible, and offer less boilerplate code than the test components. The bUnit documentation has been updated with a guide to this style.
The new package
bunit.web.testcomponentsis provided as is, without expectation of further development or enhancements. If you are using the test components currently for writing tests, it will continue to work for you. If you are starting a new project, or have few of these tests, consider switching to the "inline render fragments" style.Here is a quick comparison of the styles, using a very simple component.
First, the test component style:
@inherits TestComponentBase <Fixture Test="HelloWorldComponentRendersCorrectly"> <ComponentUnderTest> <HelloWorld /> </ComponentUnderTest> @code { void HelloWorldComponentRendersCorrectly(Fixture fixture) { // Act var cut = fixture.GetComponentUnderTest<HelloWorld>(); // Assert cut.MarkupMatches("<h1>Hello world from Blazor</h1>"); } } </Fixture> <SnapshotTest Description="HelloWorld component renders correctly"> <TestInput> <HelloWorld /> </TestInput> <ExpectedOutput> <h1>Hello world from Blazor</h1> </ExpectedOutput> </SnapshotTest>
The a single test in "inline render fragments" style covers both cases:
@inherits TestContext @code { [Fact] public void HelloWorldComponentRendersCorrectly() { // Act var cut = Render(@<HelloWorld />); // Assert cut.MarkupMatches(@<h1>Hello world from Blazor</h1>); } }To make the snapshot test scenario even more compact, consider putting all code in one line, e.g.
Render(@<HelloWorld />).MarkupMatches(@<h1>Hello world from Blazor</h1>);.For a more complete snapshot testing experience, I recommend looking at Simon Cropp's Verify library, in particular the Verify.Blazor extension to bUnit. Verify comes with all the features you expect from a snapshot testing library.
List of now removed features.
-
The
AddXunitLoggermethod, which provided support for capturingILoggermessages and passing them to xUnit'sITestOutputHelper, has been removed. There were no need to keep xUnit specific code around in bUnit going forward, and there are many implementations on-line that supports this feature, so having it in bUnit made little sense. One such alternative, which bUnit has adopted internally, is to use Serilog. This looks as follows:-
Add the following packages to your test project:
Serilog,Serilog.Extensions.Logging, andSerilog.Sinks.XUnit. -
Add the following class/extension method to your test project (which replicates the signature of the removed
AddXunitLoggermethod):```csharp using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Serilog; using Serilog.Events; using Xunit.Abstractions; namespace Bunit { public static class ServiceCollectionLoggingExtensions { public static IServiceCollection AddXunitLogger(this IServiceCollection services, ITestOutputHelper outputHelper) { var serilogLogger = new LoggerConfiguration() .MinimumLevel.Verbose() .WriteTo.TestOutput(outputHelper, LogEventLevel.Verbose) .CreateLogger(); services.AddSingleton<ILoggerFactory>(new LoggerFactory().AddSerilog(serilogLogger, dispose: true)); services.AddSingleton(typeof(ILogger<>), typeof(Logger<>)); return services; } } } ```
-
-
The
bunit.xunitpackage has been removed, since it is no longer needed (there is no code left in it).
The following section list all changes in 1.0.0 preview 02.
The plan is to make this the last preview release of bUnit. If no big blocking bugs show up the next two weeks, a non-preview release of bUnit will be pushed out to the world.
List of new features.
-
Added the ability to pass a "fallback
IServiceProvider" to theTestServiceProvider, available through theServicesproperty on aTestContext. The fallback service provider enables a few interesting scenarios, such as using an alternative IoC container, or automatically generating mocks of services components under test depend on. See the Injecting Services into Components Under Test page for more details on this feature. By @thopdev in #310. -
Added
Task<Expection> ITestRenderer.UnhandledExceptionproperty that returns aTask<Exception>that completes when the renderer captures an unhandled exception from a component under test. If a component is missing exception handling of asynchronous operations, e.g. in theOnInitializedAsyncmethod, the exception will not break the test, because it happens on another thread. To have a test fail in this scenario, you can await theUnhandledExceptionproperty on theTestContext.Rendererproperty, e.g.:using var ctx = new TestContext(); var cut = ctx.RenderComponent<ComponentThatThrowsDuringAsyncOperation>(); Task<Exception?> waitTimeout = Task.Delay(500).ContinueWith(_ => Task.FromResult<Exception?>(null)).Unwrap(); Exception? unhandledException = await Task.WhenAny<Exception?>(Renderer.UnhandledException, waitTimeout).Unwrap(); Assert.Null(unhandledException);
In this example, we await any unhandled exceptions from the renderer, or our wait timeout. The
waitTimeoutensures that we will not wait forever, in case no unhandled exception is thrown.NOTE, a better approach is to use the
WaitForStateorWaitForAssertionmethods, which now also throws unhandled exceptions. Using them, you do not need to set up a wait timeout explicitly. -
Added a simple fake navigation manager, which is registered by default in bUnit's service provider. When the fake navigation manager's
NavigateTomethod is called, it does two things:- Set the
Uriproperty to the URI passed to theNavigateTomethod (with the URI normalized to an absolute URI). - Raise the
LocationChangedevent with the URI passed to theNavigateTomethod.
Lets look at an example: To verify that the
<GoesToFooOnInit>component below calls theNavigationManager.NavigateTomethod with the expected value, do the following:<GoesToFooOnInit>component:@inject NavigationManager NavMan @code { protected override void OnInitialized() { NavMan.NavigateTo("foo"); } }
Test code:
// 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
fooinput argument is normalized to an absolute URI, we have to do the same normalization in our assertion.The fake navigation manager's
BaseUriis set tohttp://localhost/, but it is not recommended to use that URL directly in your code. Instead create an assertion by getting that value from theBaseUriproperty, like shown in the example above. - Set the
-
Added additional bUnit JSInterop
Setupmethods, that makes it possible to get complete control of invocation matching for the created handler. By @egil.
List of changes in existing functionality.
-
WaitForAssertionandWaitForStatenow throws unhandled exception caught by the renderer from a component under test. This can happen if a component is awaiting an asynchronous operation that throws, e.g. a API call using a misconfiguredHttpClient. By @egil in #310. -
Improvements to error message from bUnit's JSInterop when it receives an invocation that it has not been set up to handle. By @egil in #346.
List of now removed features.
List of any bug fixes.
The following section list all changes in 1.0.0 preview 01.
List of new features.
-
Added support for casting
BUnitJSRuntimetoIJSInProcessRuntimeandIJSUnmarshalledRuntime. By @KristofferStrube in #279 -
Added support for triggering
@ontoggleevent handlers through a dedicatedToggle()method. By @egil in #256. -
Added out of the box support for
<Virtualize>component. When a<Virtualize>component is used in a component under test, it's JavaScript interop-calls are faked by bUnits JSInterop, and it should result in all items being rendered immediately. By @egil in #240. -
Added support for components that call
ElementReference.FocusAsync. These calls are handled by the bUnits JSInterop, that also allows you to verify thatFocusAsynchas been called for a specific element. For example, if a component has rendered an<input>element, then the following code will verify that it has been focused usingFocusAsync:var cut = RenderComponent<FocusingComponent>(); var input = cut.Find("input"); JSInterop.VerifyFocusAsyncInvoke() .Arguments[0] // the first argument is the ElemenetReference .ShouldBeElementReferenceTo(input);
-
Added
Render(RenderFragment)andRender<TComponent>(RenderFragment)methods toTestContext, as well as various overloads to theMarkupMatchesmethods, that also takes aRenderFragmentas the expected value.The difference between the generic
Rendermethod and the non-generic one is that the generic returns anIRenderedComponent<TComponent>, whereas the non-generic one returns aIRenderedFragment.Calling
Render<TComponent>(RenderFragent)is equivalent to callingRender(RenderFragment).FindComponent<TComponent>(), e.g. it returns the first component in the render tree of typeTComponent. This is different from theRenderComponent<TComponent>()method, whereTComponentis the root component of the render tree.The main usecase for these are when writing tests inside .razor files. Here the inline syntax for declaring render fragments make these methods very useful.
For example, to tests the
<Counter>page/component that is part of new Blazor apps, do the following (inside aCounterTest.razorfile):@code { [Fact] public void Counter_Increments_When_Button_Is_Clicked() { using var ctx = new TestContext(); var cut = ctx.Render(@<Counter />); cut.Find("button").Click(); cut.Find("p").MarkupMatches(@<p>Current count: 1</p>); } }
Note: This example uses xUnit, but NUnit or MSTest works equally well.
In addition to the new
Rendermethods, a emptyBuildRenderTreemethod has been added to theTestContexttype. This makes it possible to inherit from theTestContexttype in test components, removing the need for newing up theTestContextin each test.This means the test component above ends up looking like this:
@inherts TestContext @code { [Fact] public void Counter_Increments_When_Button_Is_Clicked() { var cut = Render(@<Counter />); cut.Find("button").Click(); cut.Find("p").MarkupMatches(@<p>Current count: 1</p>); } }
Tip: If you have multiple test components in the same folder, you can add a
_Imports.razorfile inside it and add the@inherits TestContextstatement in that, removing the need to add it to every test component. -
Added support for
IJSRuntime.InvokeAsync<IJSObjectReference>(...)calls from components. There is now a new setup helper methods for configuring how invocations towards JS modules should be handled. This is done with the variousSetupModulemethods available on theBunitJSInteroptype available through theTestContext.JSInteropproperty. For example, to set up a module for handling calls tofoo.js, do the following:using var ctx = new TestContext(); var moduleJsInterop = ctx.JSInterop.SetupModule("foo.js");
The returned
moduleJsInteropis aBunitJSInteroptype, which means all the normalSetup<TResult>andSetupVoidmethods can be used to configure it to handle calls to the module from a component. For example, to configure a handler for a call tohelloin thefoo.jsmodule, do the following:moduleJsInterop.SetupVoid("hello");
-
Added support for registering services in bUnits
Servicescollection that implementsIAsyncDisposable. Suggested by @jmaillet in #249.
List of changes in existing functionality.
-
bUnit's mock IJSRuntime has been moved to an "always on" state by default, in strict mode, and is now available through
TestContext'sJSInteropproperty. This makes it possible for first party Blazor components like the<Virtualize>component, which depend on JSInterop, to "just work" in tests.Compatible with previous releases: To get the same effect as calling
Services.AddMockJSRuntime()in beta-11, which used to add the mock IJSRuntime in "loose" mode, you now just need to change the mode of the already on JSInterop, i.e.ctx.JSInterop.Mode = JSRuntimeMode.Loose.Inspect registered handlers: Since the new design allows registering invoke handlers in the context of the
TestContext, you might need to get already registered handlers in your individual tests. This can be done with theTryGetInvokeHandler()method, that will return handler that can handle the parameters passed to it. E.g. to get a handler for aIJSRuntime.InvokaAsync<string>("getValue"), callctx.JSInterop.TryGetInvokeHandler<string>("getValue").Learn more issue #237. By @egil in #247.
-
The
Setup<TResult>(string identifier, Func<IReadOnlyList<object?>, bool> argumentsMatcher)andSetupVoid(string identifier, Func<IReadOnlyList<object?>, bool> argumentsMatcher)methods in bUnits JSInterop/MockJSRuntime has a new second parameter, anInvocationMatcher.The
InvocationMatchertype is a delegate that receives aJSRuntimeInvoationand returns true. TheJSRuntimeInvoationtype contains the arguments of the invocation and the identifier for the invocation. This means old code using theSetupandSetupVoidmethods should be updated to use the arguments list inJSRuntimeInvoation, e.g., change the following call:ctx.JSInterop.Setup<string>("foo", args => args.Count == 2)to this:
ctx.JSInterop.Setup<string>("foo", invocation => invocation.Arguments.Count == 2). -
Changed
AddTestAuthorizationsuch that it works in Razor-based test contexts, i.e. on theFixtureandSnapshotTesttypes.
List of now removed features.
- A few bUnit internal xUnit assert helper methods, the custom
ShouldAllBemethods, has mistakingly been part of the bunit.xunit package. These have been removed.
List of any bug fixes.
-
When an
Addcall to the component parameter collection builder was used to select a parameter that was inherited from a base component, the builder incorrectly reported the selected property/parameter as missing on the type. Reported by @nickmuller in #250. -
When an element, found in the DOM tree using the
Find(), method was removed because of an event handler trigger on it, e.g. ancut.Find("button").Click()event trigger method, anElementNotFoundExceptionwas thrown. Reported by @nickmuller in #251. -
In the built-in fake authentication system in bUnit, roles and claims were not available in components through the a cascading parameter of type
Task<AuthenticationState>. Reported by @AFAde in #253 and fixed in #291 by @egil.
The following section list all changes in beta-11.
List of new features.
-
Two new overloads to the
RenderFragment()andChildContent()component parameter factory methods have been added that takes aRenderFragmentas input. By @egil in #203. -
Added a
ComponentParameterCollectiontype. TheComponentParameterCollectionis a collection of component parameters, that knows how to turn those components parameters into aRenderFragment, which will render a component and pass any parameters inside the collection to that component. That logic was spread out over multiple places in bUnit, and is now owned by theComponentParameterCollectiontype. By @egil in #203. -
Added additional placeholder services for
NavigationManager,HttpClient, andIStringLocalizer, to make it easier for users to figure out why a test is failing due to missing service registration before rendering a component. By @joro550 in #223. -
Added
Keyclass that represents a keyboard key and helps to avoid constructingKeyboardEventArgsobject manually. The key can be passed toKeyPress,KeyDown, orKeyUphelper methods to raise keyboard events. TheKeyclass provides static special keys or can be obtained from character or string. Keys can be combined with key modifiers:Key.Enter + Key.Alt.For example, this makes it easier to trigger keyboard events on an element:
var cut = ctx.RenderComponent<ComponentWithKeyboardEvents>(); var element = cut.Find("input"); element.KeyDown(Key.Enter + Key.Control); // Triggers onkeydown event with Ctrl + Enter element.KeyUp(Key.Control + Key.Shift + 'B'); // Triggers onkeyup event with Ctrl + Shift + B element.KeyPress('1'); // Triggers onkeypress event with key 1 element.KeyDown(Key.Alt + "<"); // Triggers onkeydown event with Alt + <
By @duracellko in #101.
-
Added support for registering/adding components to a test context root render tree, which components under test is rendered inside. This allows you to simplify the "arrange" step of a test when a component under test requires a certain render tree as its parent, e.g. a cascading value.
For example, to pass a cascading string value
footo all components rendered with the test context, do the following:ctx.RenderTree<CascadingValue<string>>(parameters => parameters.Add(p => p.Value, "foo")); var cut = ctx.RenderComponent<ComponentReceivingFoo>();
-
Added "catch-all"
Setupmethod to bUnit's mock JS runtime, that allows you to specify only the type when setting up a planned invocation. By @nemesv in #234.
List of changes in existing functionality.
-
The
ComponentParameterBuilderhas been renamed toComponentParameterCollectionBuilder, since it now builds theComponentParameterCollectiontype, introduced in this release of bUnit. By @egil in #203. -
ComponentParameterCollectionBuildernow allows adding cascading values that is not directly used by the component type it targets. This makes it possible to add cascading values to children of the target component. By @egil in #203. -
The
Add(object)has been replaced byAddCascadingValue(object)inComponentParameterCollectionBuilder, to make it more clear that an unnamed cascading value is being passed to the target component or one of its child components. It is also possible to pass unnamed cascading values using theAdd(parameterSelector, value)method, which now correctly detect if the selected cascading value parameter is named or unnamed. By @egil in #203. -
It is now possible to call the
Add(),AddChildContent()methods onComponentParameterCollectionBuilder, and the factory methodsRenderFragment(),ChildContent(), andTemplate(), multiple times for the same parameter, if it is of typeRenderFragmentorRenderFragment<TValue>. Doing so previously would either result in an exception or just the last passedRenderFragmentto be used. Now all the providedRenderFragmentorRenderFragment<TValue>will be combined at runtime into a singleRenderFragmentorRenderFragment<TValue>.For example, this makes it easier to pass e.g. both a markup string and a component to a
ChildContentparameter:var cut = ctx.RenderComponent<Component>(parameters => parameters .AddChildContent("<h1>Below you will find a most interesting alert!</h1>") .AddChildContent<Alert>(childParams => childParams .Add(p => p.Heading, "Alert heading") .Add(p => p.Type, AlertType.Warning) .AddChildContent("<p>Hello World</p>") ) );
-
All test doubles are now in the same namespace,
Bunit.TestDoubles. So all import statements forBunit.TestDoubles.JSInteropandBunit.TestDoubles.Authorizationmust be changed toBunit.TestDoubles. By @egil in #223. -
Marked MarkupMatches methods as assertion methods to stop SonarSource analyzers complaining about missing assertions in tests. By @egil in #229.
-
AddTestAuthorizationnow extendsTestContextinstead ofTestServiceProvider, and also automatically adds theCascadingAuthenticationStatecomponent to the root render tree. @egil in #237.
List of now removed features.
- The async event dispatcher helper methods have been removed (e.g.
ClickAsync()), as they do not provide any benefit. If you have an event that triggers async operations in the component under test, instead usecut.WaitForState()orcut.WaitForAssertion()to await the expected state in the component.
List of any bug fixes.
- Using the ComponentParameterCollectionBuilder's
Add(p => p.Param, value)method to add a unnamed cascading value didn't create an unnnamed cascading value parameter. By @egil in #203. Credits to Ben Sampica (@benjaminsampica) for reporting and helping investigate this issue. - Triggered events now bubble correctly up the DOM tree and triggers other events of the same type. This is a potentially breaking change, since this changes the behaviour of event triggering and thus you might see tests start breaking as a result hereof. By @egil in #119.
The following section list all changes in beta-10.
List of new features.
- Added support for .NET 5 RC-1.
List of changes in existing functionality.
- Related to #189, a bunch of the core
ITestRendererand related types have changed. The internals ofITestRendereris now less exposed and the test renderer is now in control of when rendered components and rendered fragments are created, and when they are updated. This enables the test renderer to protect against race conditions when theFindComponent,FindComponents,RenderFragment, andRenderComponentmethods are called.
List of any bug fixes.
- Fixes #189: The test renderer did not correctly protect against a race condition during initial rendering of a component, and that could in some rare circumstances cause a test to fail when it should not. This has been addressed in this release with a major rewrite of the test renderer, which now controls and owns the rendered component and rendered fragment instances which is created when a component is rendered. By @egil in #201. Credits to @Smurf-IV for reporting and helping investigate this issue.
This release contains a couple of fixes, and adds support for .NET Preview 8 and later. There are no breaking changes in this release.
Thanks to pharry22 for submitting fixes and improvements to the documentation.
List of new features.
- Added
InvokeAsync(Func<Task>)toRenderedComponentInvokeAsyncExtensions. By @JeroenBos in #151. - Added
ITestRenderer Renderer { get ; }toIRenderedFragmentto make it possible to simplify theIRenderedComponentBase<TComponent>interface. By @JeroenBos in #151. - Added support for scoped CSS to
MarkupMatchesand related comparer methods. By @egil in #195.
List of changes in existing functionality.
- Moved
InvokeAsync(),Render()andSetParametersAndRender()methods out ofIRenderedComponentBase<TComponent>into extension methods. By @JeroenBos in #151. - Accessing
Markup,Nodesand related methods on a rendered fragment whose underlying component has been removed from the render tree (disposed) now throws aComponentDisposedException. By @egil in #184. - Changed bUnit's build to target both .net 5.0 and .net standard 2.1. By @egil in #187.
List of any bug fixes.
- Fixes #175: When a component referenced in a test, e.g. through the
FindComponent()method was removed from the render tree, accessing the reference could caused bUnit to look for updates to it in the renderer, causing a exception to be thrown. By @egil in #184.
Here is beta-8, a small summer vacation release this time. A few needed additions, especially around testing components that use Blazor's authentication and authorization. In addition to this, a lot of documentation has been added to https://bunit.egilhansen.com/docs/getting-started/.
List of new features.
-
Authorization fakes added to make it much easier to test components that use authentication and authorization. Learn more in the Faking Blazor's Authentication and Authorization page. By @DarthPedro in #151.
-
Added
MarkupMatches(this string actual ...)extension methods. Make it easier to compare just the text content from a DON text node with a string, while still getting the benefit of the semantic HTML comparer.
List of changes in existing functionality.
TestContextBase.Disposemade virtual to allow inheritor's to override it. By @SimonCropp in #137.- [Breaking change] Changed naming convention for JSMock feature and moved to new namespace,
Bunit.TestDoubles.JSInterop. All classes and methods containingJs(meaning JavaScript) renamed toJSfor consistency with Blazor'sIJSRuntime. By @yourilima in #150
There are three big changes in bUnit in this release, as well as a whole host of small new features, improvements to the API, and bug fixes. The three big changes are:
- A splitting of the library
- Discovery of razor base tests, and
- A strongly typed way to pass parameters to a component under test.
There are also some breaking changes, which we will cover first.
NOTE: The documentation is next on the TODO list, so please bear with me while I update it to reflect all the recent changes.
Due to the big restructuring of the library, there are some breaking changes, hopefully for the better.
Previously, the Test and Setup methods on <Fixture> and <SnapshotTest> did not have any arguments, and the test context they represented when running, was implicitly available in the scope. This has changed with this release, such that all Test and Setup methods now receive the text context as an argument, and that should be used to call e.g. GetComponentUnderTest() on.
For example, if you have a razor based test that looks like this currently:
<Fixture Test="Test001" Setup="TestSetup">
<ComponentUnderTest><Counter /></ComponentUnderTest>
<Fragment>...</Fragment>
</Fixture>
@code {
void TestSetup() => Services.AddMockJsRuntime();
void Test001()
{
var cut = GetComponentUnderTest<Counter>();
var fragment = GetFragment();
}
}You have to change it to this:
<Fixture Test="Test001" Setup="TestSetup">
<ComponentUnderTest><Counter /></ComponentUnderTest>
</Fixture>
@code {
// Add a Fixture fixture argument to the setup method and use
// the services collection inside the fixture to register dependencies
void TestSetup(Fixture fixture) => fixture.Services.AddMockJsRuntime();
// Add a Fixture fixture argument to the test method
void Test001(Fixture fixture)
{
// Use the fixture instance to get the component under test
var cut = fixture.GetComponentUnderTest<Counter>();
var fragment = fixture.GetFragment();
}
}It is a little more typing, but it is also a lot more obvious what is going on, e.g. where the component under test or fragment is coming from.
In addition to this, the Tests and TestsAsync methods on <Fixture> have been deprecated in this release and throws a runtime exception if used. They were not very used and caused confusion about the state of the components under test between the method calls. Now you can only specify either a Test or TestAsync method per <Fixture>.
The WaitForRender method has been removed entirely from the library. Since it would only wait for one render, it had a very specific use case, where as the more general WaitForAssertion or WaitForState will wait for any number of renders, until the assertion passes, or the state predicate returns true. These make them much better suited to create stable tests.
With WaitForRender, you would pass in an action that would cause a render before attempting your assertion, e.g.:
cut.WaitForRender(() => mockForecastService.Task.SetResult(forecasts));
Assert.Equal("...", cut.Markup);This can now be changed to first call the action that will trigger the render, and then wait for an assertion to pass, using WaitForAssertion:
mockForecastService.Task.SetResult(forecasts);
cut.WaitForAssertion(() => Assert.Equal("...", cut.Markup));The two "wait for" methods are also only available through a rendered fragment or rendered component now.
Previously, the recommended method for creating xUnit component test classes was to inherit from ComponentTestFixture. Due to the restructuring of the library, this type is now just a TestContext with static component parameters factory methods, so it does not add much value anymore.
The component parameter factory methods are now also available in the more general purpose ComponentParameterFactory type, which can be imported into all test classes, not just xUnit ones, using the import static Bunit.ComponentParameterFactory method, and then you can change your existing xUnit test classes to inherit from TestContext instead of ComponentTestFixture to keep the current functionality for xUnit test classes.
That covers the most important breaking changes. Now lets look at the other big changes.
In this release sees bUnit refactored and split up into three different sub libraries. The reasons for doing this are:
- To make it possible to extract the direct dependency on xUnit and easily add support for NUnit or MSTest
- To make it easier to maintain distinct parts of the library going forward
- To enable future support for other non-web variants of Blazor, e.g. the Blazor Mobile Bindings.
The three parts of the library is now:
- bUnit.core: The core library only contains code related to the general Blazor component model, i.e. it is not specific to the web version of Blazor.
- bUnit.web: The web library, which has a dependency on core, provides all the specific types for rendering and testing Blazor web components.
- bUnit.xUnit: The xUnit library, which has a dependency on core, has xUnit specific extensions to bUnit, that enable logging to the test output through the
ILoggerinterface in .net core, and an extension to xUnit's test runners, that enable it to discover and run razor based tests defined in.razorfiles.
To keep things compatible with previous releases, an additional package is available, bUnit, which includes all of three libraries. That means existing users should be able to keep their single <PackageReference Include="bunit"> in their projects.
One of the pain points of writing Razor based tests in .razor files was that the individual tests was not correctly discovered. That meant that if had multiple tests in a file, you would not see them in Visual Studios Test Explorer individually, you could not run them individually, and error was not reported individually.
This has changed with the bUnit.xUnit library, that now includes a way for it to discover individual razor tests, currently either a <Fixture> or <SnapshotTest> inside test components defined in .razor files. It also enables you to navigate to the test by double clicking on it in the Test Explorer, and you can run each test individually, and see error reports individually.
WARNING: You still have to wait for the Blazor compiler to translate the .razor files into .cs files, before the tests show up in the Test Explorer, and the this can trip up the Test Explorer. So while this feature is a big improvement to razor based testing, it is still not perfect, and more works need to be done to refine it.
If you prefer writing your tests in C# only, you will be happy to know that there is now a new strongly typed way to pass parameters to components, using a builder. E.g., to render a ContactInfo component:
var cut = RenderComponent<ContactInfo>(parameters => parameters
.Add(p => p.Name, "Egil Hansen")
.Add(p => p.Country, "Iceland")
);There are a bunch of different Add methods available on the builder, that allows you to easily pass in a EventCallback, ChildContent, or RenderFragment.
The old way using the component parameter factory methods are still available if you prefer that syntax.
NOTE: The parameter builder API is experimental at this point, and will likely change.
The latest version of the library is available on NuGet in various incarnations:
Thanks to Martin Stühmer (@samtrion) and Stef Heyenrath (@StefH) for their code contributions in this release, and to Brad Wilson (@bradwilson) for his help with enabling xUnit to discover and run Razor based tests.
Also a big thank to all you who have contributed by raising issues, participated in issues by helping answer questions and providing input on design and technical issues.
- A new event,
OnAfterRender, has been added toIRenderedFragmentBase, whichIRenderedFragmentinherits from. Subscribers will be invoked each time the rendered fragment is re-rendered. Related issue #118. - A new property,
RenderCount, has been added toIRenderedFragmentBase, whichIRenderedFragmentinherits from. Its represents the number of times a rendered fragment has been rendered. Related issue #118. - A new event,
OnMarkupUpdated, has been added toIRenderedFragmentBase. Subscribers will be notifid each time the rendered fragments markup has been regenerated. Related issue #118. - Due to the concurrency bug discovered, the entire render notification and markup notification system has been changed.
- A new overload
RenderComponent()andSetParameterAndRender(), which takes aAction<ComponentParameterBuilder<TComponent>>as input. That allows you to pass parameters to a component under test in a strongly typed way. Thanks to @StefH for the work on this. Related issues: #79 and #36. - The two razor test types,
<Fixture>and<SnapshotTest>, can now be skipped. by setting theSkip="some reason for skipping"parameter. Note, this requires support from the test runner, which current only includes bUnit.xUnit. Related issue: #77. - The two razor test types,
<Fixture>and<SnapshotTest>, can now have a timeout specified, by setting theTimeout="TimeSpan.FromSeconds(2)"parameter. Note, this requires support from the test runner, which current only includes bUnit.xUnit. - An
InvokeAsyncmethod has been added to theIRenderedFragmentBasetype, which allows invoking of an action in the context of the associated renderer. Related issue: #82. - Enabled the "navigate to test" in Test Explorer. Related issue: #106.
- Enabled xUnit to discover and run Razor-based tests. Thanks to Brad Wilson (@bradwilson) for his help with this. Related issue: #4.
- Better error description from
MarkupMatcheswhen two sets of markup are different. - The
JsRuntimePlannedInvocationcan now has its response to an invocation set both before and after an invocation is received. It can also have a new response set at any time, which will be used for new invocations. Related issue: #78. - The
IDiffassertion helpers likeShouldHaveChangesnow takes anIEnumerable<IDiff>as input to make it easier to call in scenarios where only an enumerable is available. Related issue: #87. TextContextnow registers all its test dependencies as services in theServicescollection. This now includes theHtmlParserandHtmlComparer. Related issue: #114.
- The
ComponentTestFixturehas been deprecated in this release, since it just inherits fromTestContexand surface the component parameter factory methods. Going forward, users are encouraged to instead inherit directly fromTestContextin their xUnit tests classes, and add aimport static Bunit.ComponentParameterFactoryto your test classes, to continue to use the component parameter factory methods. Related issue: #108.
<Fixture>tests no longer supports splitting the test method/assertion step into multiple methods through theTestsandTestsAsyncparameters.WaitForRenderhas been removed entirely from the library, as the more general purposeWaitForAssertionorWaitForStatecovers its use case.WaitForAssertionorWaitForStateis no longer available onITestContexttypes. They are still available on rendered components and rendered fragments.CreateNodesmethod has been removed fromITextContext. The ability to convert a markup string to aINodeListis available through theHtmlParsertype registered inITextContext.Servicesservice provider.RenderEventshas been removed fromIRenderedFragment, and replaced by theOnMarkupUpdatedandOnAfterRenderevents. Related issue #118.- The generic collection assertion methods
ShouldAllBe<T>(this IEnumerable<T> collection, params Action<T, int>[] elementInspectors)andShouldAllBe<T>(this IEnumerable<T> collection, params Action<T>[] elementInspectors)have been removed from the library.
- A concurrency issue would surface when a component under test caused asynchronous renders that was awaited using the
WaitForRender,WaitForState, orWaitForAssertionmethods. Related issue #118. MarkupMatchesand the related semantic markup diffing, didn't correctly ignore the__internal_stopPropagation_and__internal_preventDefault_added by Blazor to the rendered markup, when users use the:stopPropagationand:preventDefaultmodifiers. Thanks to @samtrion for reporting and solving this. Related issue: #111.cut.FindComponent<TComponent>()didn't return the component inside the component under test. It now searches and finds the first child component of the specified type.
This release includes a name change from Blazor Components Testing Library to bUnit. It also brings along two extra helper methods for working with asynchronously rendering components during testing, and a bunch of internal optimizations and tweaks to the code.
Why change the name? Naming is hard, and I initial chose a very product-namy name, that quite clearly stated what the library was for. However, the name isn't very searchable, since it just contains generic keywords, plus, bUnit is just much cooler. It also gave me the opportunity to remove my name from all the namespaces and simplify those.
Hugh thanks to Rastislav Novotný (@duracellko)) for his input and review of the WaitForX logic added in this release.
The latest version of the library is availble on NuGet:
| Type | Link | |
|---|---|---|
| Library | https://www.nuget.org/packages/bunit/ | |
| Template | https://www.nuget.org/packages/bunit.template/ |
-
WaitForState(Func<bool> statePredicate, TimeSpan? timeout = 1 second)has been added toITestContextandIRenderedFragment.
This method will wait (block) until the provided statePredicate returns true, or the timeout is reached (during debugging the timeout is disabled). Each time the renderer in the test context renders, or the rendered fragment renders, the statePredicate is evaluated.You use this method, if you have a component under test, that requires one or more asynchronous triggered renders, to get to a desired state, before the test can continue.
The following example tests the
DelayedRenderOnClick.razorcomponent:// DelayedRenderOnClick.razor <p>Times Clicked: @TimesClicked</p> <button @onclick="ClickCounter">Trigger Render</button> @code { public int TimesClicked { get; private set; } async Task ClickCounter() { await Task.Delay(1); // wait 1 millisecond TimesClicked += 1; } }
This is a test that uses
WaitForStateto wait until the component under test has a desired state, before the test continues:[Fact] public void WaitForStateExample() { // Arrange var cut = RenderComponent<DelayedRenderOnClick>(); // Act cut.Find("button").Click(); cut.WaitForState(() => cut.Instance.TimesClicked == 1); // Assert cut.Find("p").TextContent.ShouldBe("Times Clicked: 1"); }
-
WaitForAssertion(Action assertion, TimeSpan? timeout = 1 second)has been added toITestContextandIRenderedFragment.
This method will wait (block) until the provided assertion method passes, i.e. runs without throwing an assert exception, or until the timeout is reached (during debugging the timeout is disabled). Each time the renderer in the test context renders, or the rendered fragment renders, the assertion is attempted.You use this method, if you have a component under test, that requires one or more asynchronous triggered renders, to get to a desired state, before the test can continue.
This is a test that tests the
DelayedRenderOnClick.razorlisted above, and that usesWaitForAssertionto attempt the assertion each time the component under test renders:[Fact] public void WaitForAssertionExample() { // Arrange var cut = RenderComponent<DelayedRenderOnClick>(); // Act cut.Find("button").Click(); // Assert cut.WaitForAssertion( () => cut.Find("p").TextContent.ShouldBe("Times Clicked: 1") ); }
-
Added support for capturing log statements from the renderer and components under test into the test output.
To enable this, add a constructor to your test classes that takes theITestOutputHelperas input, then in the constructor callServices.AddXunitLoggerand pass theITestOutputHelperto it, e.g.:// ComponentTest.cs public class ComponentTest : ComponentTestFixture { public ComponentTest(ITestOutputHelper output) { Services.AddXunitLogger(output, minimumLogLevel: LogLevel.Debug); } [Fact] public void Test1() ... }
For Razor and Snapshot tests, the logger can be added almost the same way. The big difference is that it must be added during Setup, e.g.:
// RazorComponentTest.razor <Fixture Setup="Setup" ...> ... </Fixture> @code { private ITestOutputHelper _output; public RazorComponentTest(ITestOutputHelper output) { _output = output; } void Setup() { Services.AddXunitLogger(_output, minimumLogLevel: LogLevel.Debug); } }
-
Added simpler
Templatehelper method
To make it easier to test components withRenderFragment<T>parameters (template components) in C# based tests, a newTemplate<TValue>(string name, Func<TValue, string> markupFactory)helper methods have been added. It allows you to create a mock template that uses themarkupFactoryto create the rendered markup from the template.This is an example of testing the
SimpleWithTemplate.razor, which looks like this:@typeparam T @foreach (var d in Data) { @Template(d); } @code { [Parameter] public RenderFragment<T> Template { get; set; } [Parameter] public IReadOnlyList<T> Data { get; set; } = Array.Empty<T>(); }
And the test code:
var cut = RenderComponent<SimpleWithTemplate<int>>( ("Data", new int[] { 1, 2 }), Template<int>("Template", num => $"<p>{num}</p>") ); cut.MarkupMatches("<p>1</p><p>2</p>");
Using the more general
Templatehelper methods, you need to write theRenderTreeBuilderlogic yourself, e.g.:var cut = RenderComponent<SimpleWithTemplate<int>>( ("Data", new int[] { 1, 2 }), Template<int>("Template", num => builder => builder.AddMarkupContent(0, $"<p>{num}</p>")) );
-
Added logging to TestRenderer. To make it easier to understand the rendering life-cycle during a test, the
TestRendererwill now log when ever it dispatches an event or renders a component (the log statements can be access by capturing debug logs in the test results, as mentioned above). -
Added some of the Blazor frameworks end-2-end tests. To get better test coverage of the many rendering scenarios supported by Blazor, the ComponentRenderingTest.cs tests from the Blazor frameworks test suite has been converted from a Selenium to a bUnit. The testing style is very similar, so few changes was necessary to port the tests. The two test classes are here, if you want to compare:
-
Namespaces is now
Bunit
The namespaces have changed fromEgil.RazorComponents.Testing.Library.*to simplyBunitfor the library, andBunit.Mocking.JSInteropfor the JSInterop mocking support. -
Auto-refreshing
IElements returned fromFind()
IRenderedFragment.Find(string cssSelector)now returns aIElement, which internally will refresh itself, whenever the rendered fragment it was found in, changes. This means you can now search for an element once in your test and assign it to a variable, and then continue to assert against the same instance, even after triggering renders of the component under test.For example, instead of having
cut.Find("p")in multiple places in the same test, you can dovar p = cut.Find("p")once, and the use the variablepall the places you would otherwise have theFind(...)statement. -
Refreshable element collection returned from
FindAll.
TheFindAllquery method onIRenderedFragmentnow returns a new type, theIRefreshableElementCollection<IElement>type, and the method also takes a second optional argument now,bool enableAutoRefresh = false.The
IRefreshableElementCollectionis a special collection type that can rerun the query to refresh its the collection of elements that are found by the CSS selector. This can either be done manually by calling theRefresh()method, or automatically whenever the rendered fragment renders and has changes, by setting the propertyEnableAutoRefreshtotrue(default set tofalse).Here are two example tests, that both test the following
ClickAddsLi.razorcomponent:<ul> @foreach (var x in Enumerable.Range(0, Counter)) { <li>@x</li> } </ul> <button @onclick="() => Counter++"></button> @code { public int Counter { get; set; } = 0; }
The first tests uses auto refresh, set through the optional parameter
enableAutoRefreshpassed to FindAll:public void AutoRefreshQueriesForNewElementsAutomatically() { var cut = RenderComponent<ClickAddsLi>(); var liElements = cut.FindAll("li", enableAutoRefresh: true); liElements.Count.ShouldBe(0); cut.Find("button").Click(); liElements.Count.ShouldBe(1); }
The second test refreshes the collection manually through the
Refresh()method on the collection:public void RefreshQueriesForNewElements() { var cut = RenderComponent<ClickAddsLi>(); var liElements = cut.FindAll("li"); liElements.Count.ShouldBe(0); cut.Find("button").Click(); liElements.Refresh(); // Refresh the collection liElements.Count.ShouldBe(1); }
-
Custom exception when event handler is missing. Attempting to triggering a event handler on an element which does not have an handler attached now throws a
MissingEventHandlerExceptionexception, instead of anArgumentException.
WaitForNextRenderhas been deprecated (marked as obsolete), since the addedWaitForStateandWaitForAssertionprovide a much better foundation to build stable tests on. The plan is to remove completely from the library with the final 1.0.0 release.
-
AddMockHttpand related helper methods have been removed.
The mocking of HTTPClient, supported through the mockhttp library, has been removed from the library. This was done because the library really shouldn't have a dependency on a 3. party mocking library. It adds maintenance overhead and uneeded dependencies to it.If you are using mockhttp, you can easily add again to your testing project. See TODO Guide to mocking HttpClient in the docs to learn how.
- Wrong casing on keyboard event dispatch helpers.
The helper methods for the keyboard events was not probably cased, so that has been updated. E.g. fromKeypress(...)toKeyPress(...).