Megabit / Blazorise

Blazorise is a component library built on top of Blazor with support for CSS frameworks like Bootstrap, Tailwind, Bulma, AntDesign, and Material.
https://blazorise.com/
Other
3.29k stars 531 forks source link

BUnit Interop for Tooltip #5035

Closed rbillott closed 1 year ago

rbillott commented 1 year ago

Is your feature request related to a problem? Please describe. I have been using BUnit to test my Razor code with bunch of Blazorise component pretty successfully so far using a copy of BlazoriseConfig.cs One of my component was using a Blazorise Tooltip and I could find the related helper to mock the module.

So I crafted below version based on other mocking which seems to work..

public static void AddTooltip(BunitJSInterop jsInterop)
        {
            var module = jsInterop.SetupModule(new BootstrapJSTooltipModule(jsInterop.JSRuntime, new VersionProvider()).ModuleFileName);

            module.SetupVoid( "initialize", _ => true ).SetVoidResult();
            module.SetupVoid( "destroy", _ => true ).SetVoidResult();
            module.SetupVoid( "updateContent", _ => true ).SetVoidResult();
        }

Just want to check if that make sense and maybe it can be integrated in the code base..

David-Moreira commented 1 year ago

Thanks for the suggestion @rbillott .

Please find this related issue where we plan to provide an helper package which should have helpers like this and be a more complete package. https://github.com/Megabit/Blazorise/issues/4977

Going ahead and closing the issue, you can leave any other suggestions in that issue, we appreciate it!

rbillott commented 1 year ago

That's great initiative to have a package that contains the helper code for Bunit (and other frameworks)

I just want to share some helpers I coded in my project on top the ones I found here. I have an extension I call wherever I need it from a Razor Test class, and also a custom attribute that list the needed components.

    public static class BlazoriseTestExtension
    {
        public static void SetupBlazorise(this TestContext context)
        {
            // don't recall well why this is needed
            context.Services.AddBlazorise().Replace(ServiceDescriptor.Transient<IComponentActivator, ComponentActivator>());
            BlazoriseConfig.AddBootstrapProviders(context.Services);

            if (Attribute.GetCustomAttribute(context.GetType(), typeof (BlazoriseJSInteropAttribute)) is BlazoriseJSInteropAttribute attribute)
            {
                foreach (var name in attribute.Names)
                {
                    var methodInfo = typeof(BlazoriseConfig.JSInterop).GetMethod($"Add{name}");
                    if (methodInfo == null) throw new ArgumentException($"<{name}> is not a valid Blazorise component name or there is no interop support");
                    methodInfo.Invoke(null, new object?[]{context.JSInterop});
                }
            }
        }
    }

    [AttributeUsage(AttributeTargets.Class)]
    public class BlazoriseJSInteropAttribute : Attribute
    {
        internal string[] Names { get; }
        public BlazoriseJSInteropAttribute(params string[] names)  {  Names = names;   }
    }

And below is a test class to demonstrate the usage

    [BlazoriseJSInterop("Button","DataGrid","Breakpoint")]
    public class MyPageTest : TestContext
    {
        public MyPageTest ()
        {
            this.SetupBlazorise();
        }

        [Fact]
        public void MyPageTest_ShouldRenderCorrectly()
        {

            // Act
            var cut = RenderComponent<MyPage>();

            // Assert
            Assert.NotNull(cut.Find("div#Xxxx"));