MatBlazor
MatBlazor copied to clipboard
IMatDialogService + BUnit
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.
<MatPortalHost></MatPortalHost>
maybe it has something to do with it, but I'm not sure how to enable it in BUnit.
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
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.
Did you try:
ctx.RenderTree.TryAdd<MatPortalHost>();
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.
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.
[CascadingParameter]
public MatDialogReference DialogReference { get; set; }
is this necessary. Furthermore:
// in root Blazor app component - App.razor
<MatPortalHost></MatPortalHost>
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.
@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.
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.
there is no error message. the execution just stops.
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.
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.