bUnit-dev / bUnit

bUnit is a testing library for Blazor components that make tests look, feel, and runs like regular unit tests. bUnit makes it easy to render and control a component under test’s life-cycle, pass parameter and inject services into it, trigger event handlers, and verify the rendered markup from the component using a built-in semantic HTML comparer.
https://bunit.dev
MIT License
1.13k stars 105 forks source link

Submit on form with Required Field Validations does not call the defined OnValidSubmit method #55

Closed jpiell closed 4 years ago

jpiell commented 4 years ago

Describe the bug If a component used validation as described in ASP.NET Core Blazor forms and validation: https://docs.microsoft.com/en-us/aspnet/core/blazor/forms-validation?view=aspnetcore-3.1

Submit on the form will not call the method defined in the property OnValidSubmit of the EditForm tag.

Example: Example app is attached. TelerikBlazorApp1.zip

Component under test
FetchData

With this test:

Unit test in C# or Razor or Snapshot that fails.
```FetchDataRendersCorrectly

Results in this output:
Save method never called
```text
Message output from running the test.

Expected behavior: A clear and concise description of what you expected to happen.

I expect if the component passes validation the method defined on OnValidSubmit to be called. The test acts like validation is never passed.

Version info:

Additional context: Add any other context about the problem here.

egil commented 4 years ago

Hi @jpiell

Can you submit a example that does not depend on the Telerik components. I do not have a license, and your issue is not related to them. Try to keep the example as minimal as possible. Remove all unneeded code that is not part of the problem.

jpiell commented 4 years ago

Attached is a sample app that does not reference Telerik. BlazorApp1.zip

egil commented 4 years ago

You cannot fill in input fields with .TextContent. Instead, use the .Change(...) method instead. E.g.

[Fact]
public void FetchDataRendersCorrectly()
{
    Services.AddSingleton<WeatherForecastService>();

    var cut = RenderComponent<FetchData>();

    cut.Find("#Summary_textbox").Change("test");

    cut.Find("form").Submit();
}

You previous test never actually set the summary text box, so the validation never passed.

jpiell commented 4 years ago

You cannot fill in input fields with .TextContent. Instead, use the .Change(...) method instead. E.g.

[Fact]
public void FetchDataRendersCorrectly()
{
    Services.AddSingleton<WeatherForecastService>();

    var cut = RenderComponent<FetchData>();

    cut.Find("#Summary_textbox").Change("test");

    cut.Find("form").Submit();
}

You previous test never actually set the summary text box, so the validation never passed.

What if the control is a booliean vs text.

eg; <MatSlideToggle Id="Active_slider" @bind-Value="@SelectedGridItem.Active" Label=" Active">

jpiell commented 4 years ago

Active is a bool

egil commented 4 years ago

@jpiell that will be fixed in the next release. Then you can pass anything to the Change method.

Workaround for now is:

cut.Find("...").TriggerEventAsync("onchange", new ChangeEventArgs());

Where you set whatever value you want in the ChangeEventArgs type.

jpiell commented 4 years ago

Another question is about async Save methods. Apparently these can run after the test has concluded.

Is there a way to get the component under test to wait until all threads have completed?