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

How to render EditForm in C#? #104

Closed Xeevis closed 4 years ago

Xeevis commented 4 years ago

I'd like to test EditContext validation when some custom component is added to EditForm, but have two issues rendering the EditForm.

Can't use Model parameter to create EditContext

var cut = this.RenderComponent<EditForm>(
    Parameter(nameof(EditForm.Model), new SampleModel())
);

cut.Instance.EditContext.ShouldNotBeNull(); // throws exception

It appears EditForm.OnParametersSet() is not called, because if I pass in EditContext directly it works

var cut = this.RenderComponent<EditForm>(
    Parameter(nameof(EditForm.EditContext), new EditContext(new SampleModel()))
);

cut.Instance.EditContext.ShouldNotBeNull(); // OK

Can't use ChildContent to include inputs or other components

var cut = this.RenderComponent<EditForm>(
    Parameter(nameof(EditForm.EditContext), new EditContext(new SampleModel())),
    ChildContent<InputText>(Parameter("class", "form-control"))
); 

This throw exception

System.InvalidOperationException : Unable to set property 'ChildContent' on object of type 'EditForm'. The error was: Unable to cast object of type 'RenderFragment' to type 'RenderFragment`1[EditContext]'.

Any ideas how to get it working? Thanks.

egil commented 4 years ago

Hi Xeevis,

After reading the source for EditForm I am not sure why your first example isnt working. According to the code, if you only provide a Model everything should be OK.

Can you post your entire test class so I can get the full picture, as well as the version of blazor and bunit?

Xeevis commented 4 years ago

Hi egil, yeah should, but doesn't in the RenderComponent<> 😓

Version info: bunit 1.0.0-beta-6 .net core 3.1 Solution: BUnitEditForm.zip

public class EditFormTest : ComponentTestFixture
{
    [Fact]
    public void RenderEditForm()
    {
        var cut = RenderComponent<EditForm>(
            Parameter(nameof(EditForm.Model), new SampleModel())
        );

        cut.Instance.EditContext.ShouldNotBeNull();
    }
}

public class SampleModel
{
    public string Username { get; set; }
}
egil commented 4 years ago

Just did a quick debug, and OnParameterSet is indeed called. If you look a the code for EditForm, nothing sets the EditContext property inside OnParameterSet, so everything is as expected. What is set is the private _fixedEditContext, which is set by OnParameterSet on this line. See screenshot below:

image

Closing since this looks like it works as expected.