MatBlazor icon indicating copy to clipboard operation
MatBlazor copied to clipboard

IMatDialogService + BUnit

Open drma-tech opened this issue 4 years ago • 14 comments

I don't know if you guys use BUnit, component to test Blazor.

I'm trying to initialize the IMatDialogService, but I can't manually initialize this service. ctx.RegisterDialogService(typeof(ChangeDialog), new());

public static void RegisterDialogService(this TestContext ctx, Type componentType, Dictionary<string, object> attributes)
{
    var services = new MatPortalService();
    services.Add(componentType, attributes);
    ctx.Services.AddSingleton<IMatDialogService>(new MatDialogService(services));
}
var cut = ctx.RenderComponent<ChangeDialog>(parameters => parameters
    .Add(p => p.DialogReference, new MatDialogReference() { Service = new MatDialogService(new MatPortalService()) })
);
var att = new Dictionary<string, object>
{
    { "VariableName", "xyz" },
    { "VariableValue", "xyz" },
    { "VariableType", VariableType.SingleLine }
};

await cut.Instance.DialogReference.Service.OpenAsync(typeof(ChangeDialog), new MatDialogOptions() { Attributes = att });

when I run that last line of code, the system crashes.

drma-tech avatar Oct 25 '21 15:10 drma-tech

<MatPortalHost></MatPortalHost>

maybe it has something to do with it, but I'm not sure how to enable it in BUnit.

drma-tech avatar Oct 25 '21 16:10 drma-tech

If MatBlazor needs a root component to be added in App.razor, then this might be what you need: https://bunit.dev/docs/providing-input/root-render-tree.html

egil avatar Oct 25 '21 16:10 egil

I think so, but I still can't make it work.

ctx.RenderTree.TryAdd<CascadingValue<MatPortalHost>>(parameters => parameters
    .Add(p => p.Value, new MatPortalHost())
);

ctx.RenderTree.TryAdd<CascadingValue<MatDialogReference>>(parameters => parameters
    .Add(p => p.Value, new MatDialogReference() { Service = new MatDialogService(new MatPortalService()) })
);

I tried these two together, alone, but it seems to have no effect.

drma-tech avatar Oct 25 '21 18:10 drma-tech

Did you try:

ctx.RenderTree.TryAdd<MatPortalHost>();

egil avatar Oct 25 '21 19:10 egil

System.ArgumentException : The MatBlazor.MatPortalHost does not have a ChildContent or Body parameter. Only components with one of these parameters can be added to the root render tree.

drma-tech avatar Oct 25 '21 19:10 drma-tech

Then MatPortalHost doesn't provide a cascading value. So are you sure you need it?

You may need to add a service to Services though. Take a look at the docs for the component to figure out it's dependencies.

egil avatar Oct 25 '21 19:10 egil

    [CascadingParameter]
    public MatDialogReference DialogReference { get; set; }

is this necessary. Furthermore:

// in root Blazor app component - App.razor <MatPortalHost></MatPortalHost>

drma-tech avatar Oct 25 '21 19:10 drma-tech

this is not necessarily a cascading father (because you have to put it in app.razor). I don't even know if that's the problem, it was just a possibility.

await cut.Instance.DialogReference.Service.OpenAsync(typeof(ChangeDialog), new MatDialogOptions() { Attributes = att });

I know it stops on that line. does not give error or anything.

drma-tech avatar Oct 25 '21 20:10 drma-tech

@egil

<MatPortalHost></MatPortalHost>

how can i declare this like it was in app.razor? because this RenderTree you mentioned as far as I understand only registers parent components, not necessarily something that is in the app.

I think that's what's missing for me to be able to correctly register the services.

drma-tech avatar Oct 26 '21 21:10 drma-tech

when I run that last line of code, the system crashes.

To get more help, you might want to share what the exception message is.

egil avatar Oct 30 '21 07:10 egil

there is no error message. the execution just stops.

drma-tech avatar Oct 30 '21 15:10 drma-tech

there is no error message. the execution just stops.

So the system doesn't crash as you wrote before, the test completes without an error?

I don't know how the MadDialog works, but my guess is that it calls triggers something in a other component, perhaps in MatPortalHost, and that shows the dialog.

So the question is. Why would you want to test the internal dialog feature of MadBlazor?

Why not just render the content you want to show in the dialog and trust that the dialog itself works correctly.

Sorry, it's super hard to help any more. I'm not a MadBlazor dev, so don't know how it works.

egil avatar Oct 30 '21 16:10 egil

I don't know what the word crash means exactly.

but the execution stops, doesn't finish. if you debug the method, debugging will stop at that line, and not continue. as if there was an internal error, but this exception doesn't come back to you, so you don't know what's going on.

I use this functionality to open a popup a lot, so my test has to respect that, to be as close as possible to an interacting user.

drma-tech avatar Oct 30 '21 16:10 drma-tech