Skip to content

Unable to Simulate User Interaction for FluentCheckbox of Blazor Fluent Component via UI in bUnit A #1739

Description

@moh-hassan

This issue is posted on stackoverflow , but no answer.

When trying to test a component that use Fluent UI Blazor library <FluentCheckbox> with bUnit, test fail because user interaction is not applied.

The Environment:

  • Blazor server, net8
  • Using Microsoft.FluentUI.AspNetCore.Components library
  • Bunit 1.40.0
  • Nunit 3
  • vs 2022

The component source code is:

@using App.Model
<!--TeamOptionComp-->

@foreach (var option in Options)
{
    <FluentCheckbox @bind-Value="option.IsSelected">
        @option.Name
    </FluentCheckbox>
}

@code {
    [Parameter]
    public List<TeamOption> Options { get; set; } = new();
}


The bunit test is:

 [Test]
 public void Selecting_checkbox_updates_model()
 {
     // Arrange
     var options = new List<TeamOption>
     {
         new TeamOption { Name = "Option 1", IsSelected = false},
         new TeamOption { Name = "Option 2", IsSelected = false }
     };

     using var ctx = new Bunit.TestContext();
     ctx.Services.AddFluentUIComponents();
     var cut = ctx.RenderComponent<TeamOptionComp>(parameters => parameters
         .Add(p => p.Options, options)
     );
     Console.WriteLine(cut.Markup);
     // Act	
     var checkboxes = cut.FindAll("fluent-checkbox");

     //Simulate user interaction
     // 1) Simulate clicking the first checkbox
     //checkboxes[0].Click();// it throws an exception because the FluentCheckbox does not have an 'onclick' event handler.

     // 2)Using Change in  the first checkbox
     //  checkboxes[0].Change(true);// it throws an exception because the FluentCheckbox does not have an 'onchange' event handler.

     //3) using TriggerEvent, supported but has no effect
     checkboxes[0].TriggerEvent("oncheckedchange", new CheckboxChangeEventArgs { Checked = true });
     cut.Render(); 
    
      //update checkboxes after the change
     checkboxes = cut.FindAll("fluent-checkbox");

     //Assert
     Assert.That(options[0].IsSelected, Is.True, "options[0] should be checked");
     Assert.That(options[1].IsSelected, Is.False);

     //Assert markup updates as well
     Assert.That(checkboxes[0].ClassList, Does.Contain("checked"), "First checkbox should have 'checked' class");
    Assert.That(checkboxes[1].ClassList, Does.Not.Contain("checked"), "Second checkbox should not have 'checked' class");
 
 }
  • In the above test,the test fail. I am unable to simulate user interaction that updates the bound model property using TriggerEvent in bUnit .

  • <FluentCheckbox> does not support calling .Change(true) or Click()

  • Attempting to use .TriggerEvent() has no effect.

Is there a recommended bUnit approach to simulate user interaction (checking/unchecking) for FluentCheckbox that causes the model to update as it would in a browser?

Note: The component uses @bind-Value, and the only reliable way is to update from model to UI by setting the bound value directly and re-render. This does not simulate a real user interaction.

Thanks for your help!

Activity

  1. linkdotnet commented on Aug 1, 2025

    @linkdotnet
    Collaborator

    Egil and I are currently one holiday so can only use mobile right now:
    To interact with the bind directive we have a whole chapter in our docs: https://bunit.dev/docs/providing-input/passing-parameters-to-components.html?tabs=csharp#configure-two-way-with-component-parameters-bind-directive

    My personal opinion would be not to rely on their party and instead try to mock/fake the component (3rd party) with a test double. This can be achieved via: https://bunit.dev/docs/providing-input/substituting-components.html?tabs=moq

  2. moh-hassan commented on Aug 4, 2025

    @moh-hassan
    Author

    Thanks @linkdotnet for reply.
    I can't use two-way binding approach because i don't use EventCallback. i use only @bind-value for every checkbox as documented.

    Also, using cut.WaitForAssertion with timeout don't help and I find more iteration inside it.

    The only way to fix the issue is to add a delay before Assert, like

    //add 100ms delay for UI to be updated after TriggerEvent
    Task.Delay(100).Wait()
    

    It seem that the TriggerEvent has not finished updating the UI and rededering is still in progress.

  3. linkdotnet commented on Aug 4, 2025

    @linkdotnet
    Collaborator

    If that is the case and there are async updates, you should use the WaitForXXX helpers: https://bunit.dev/docs/interaction/awaiting-async-state.html

  4. linkdotnet commented on Aug 4, 2025

    @linkdotnet
    Collaborator

    I will convert this into a discussion as this isn't a bug per-se.

  5. locked and limited conversation to collaborators on Aug 4, 2025
  6. converted this issue into a discussion #1740 on Aug 4, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions