2

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!

mu88
  • 4,156
  • 1
  • 23
  • 47

1 Answers1

3

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();
        }

dani herrera
  • 48,760
  • 8
  • 117
  • 177
  • Thank you! Maybe it's worth being mentioned [here](https://bunit.dev/docs/interaction/trigger-event-handlers.html?tabs=csharp)? – mu88 May 02 '22 at 08:24
  • @mu88, sure. Or in a special topic "how to invoke custom EventCallback". Any case, bunit is awesome. – dani herrera May 02 '22 at 09:08