Test event handler of InputFile in Blazor component with bUnit

1.5k Views Asked by At

I have a Blazor component like this:

// MyComponent.razor

<InputFile id="input-file" OnChange="@LoadImage" accept=".jpg,.jpeg,.png"/>

@code {
    internal IBrowserFile? File;

    private void LoadImage(InputFileChangeEventArgs args) => File = args.File;
}

I want to test the event handler of this component using bUnit with the following test:

[Test]
public void UploadFile()
{
    // Arrange
    var browserFile = new Mock<IBrowserFile>().Object;
    var ctx = new TestContext();
    var testee = ctx.RenderComponent<MyComponent>

    // Act
    testee.Find("[id^=\"input-file\"]").Change(new InputFileChangeEventArgs(new []{browserFile}));

    // Assert
    testee.Instance.File.Should().Be(browserFile);
}

This test fails with the following error:

Bunit.MissingEventHandlerException : The element does not have an event handler for the event 'onchange', nor any other events.
   at Bunit.TriggerEventDispatchExtensions.TriggerNonBubblingEventAsync(ITestRenderer renderer, IElement element, String eventName, EventArgs eventArgs) in /_/src/bunit.web/EventDispatchExtensions/TriggerEventDispatchExtensions.cs:line 144
   at Bunit.InputEventDispatchExtensions.ChangeAsync(IElement element, ChangeEventArgs eventArgs) in /_/src/bunit.web/EventDispatchExtensions/InputEventDispatchExtensions.cs:line 36
   at Bunit.InputEventDispatchExtensions.Change[T](IElement element, T value) in /_/src/bunit.web/EventDispatchExtensions/InputEventDispatchExtensions.cs:line 18

So how can I trigger Blazor's OnChange event of an InputFile?

Thanks!

1

There are 1 best solutions below

2
On BEST ANSWER

Is full documented at Testing components that uses the component discussion, invoke OnChange on component. In your code:

var testee = ctx.RenderComponent<MyComponent>();

var filesToUpload = new InputFileChangeEventArgs(new []{browserFile});
var inputComponent = testee.FindComponent<InputFile>().Instance;

// Invoke the OnChange event callback to emulate the
// user uploading one or more files
await cut.InvokeAsync(() => 
    inputComponent.OnChange.InvokeAsync(filesToUpload));

// ...

Important part:

To work with InputFile you must to setup your JSInterop. Use a TestContext class instead to create your context by hand (avoid this: ctx = new TestContext(); ):

    public class FileUpload1Test : TestContext
    {
        public FileUpload1Test()
        {
            // FileInput component configuration
            Services.AddSingleton(Options.Create(new RemoteBrowserFileStreamOptions()));
            JSInterop.SetupVoid(invocation => invocation.Identifier == "Blazor._internal.InputFile.init")
                .SetVoidResult();
        }