Open Closed

Exception When creating BUnit tests for Blazor #1979


0
[email protected] created

Hi,

When creating a Unit test using BUnit I get the following issue when unit testing. The question I have is, are there a set of best practices to follow when using BUnit for unit testing? It appears any Blazor component inheriting from AbpComponentBase, will need to mock a lot of classes up front in order for the test to execute. Do you have some examples I could follow along for my unit testing? When I look at the documentation I see that examples will be coming soon. Please see the link : https://docs.abp.io/en/abp/latest/UI/Blazor/Testing

If you have any BUnit documentation, specifically for the ABP framework, that would be very helpful.

Thanks,

Jesse

  • ABP Framework version: Latest
  • UI type: Blazor
  • DB provider: EF Core
  • Tiered (MVC) or Identity Server Separated (Angular): no
  • Exception message and stack trace:

Volo.Abp.AbpException HResult=0x80131500 Message=authorizationService should implement Volo.Abp.Authorization.IAbpAuthorizationService Source=Volo.Abp.Authorization


7 Answer(s)
  • 0
    albert created
    Support Team

    @maliming will help you on that.

  • 0
    maliming created
    Support Team

    hi Thomas

    Can you share your steps and code to reproduce the problem?

  • 0
    [email protected] created

    Hi Maliming,

    I have a method in my razor.cs class :

          protected virtual async Task SetPermissionsAsync()
            {
                HasEditPermission =  await AuthorizationService.IsGrantedAsync(UpdatePolicyName);
            }
    

    This returns an IAuthorizationService, and comes from the static class AbpAuthorizationServiceExtensions. This method is first Initialized in the following start up method in the razor component:

            protected override async Task OnInitializedAsync()
            {
                await SetPermissionsAsync();
            }
    

    This is where the error occurs. I need to pass an instance of the IAuthorizationService to the component during the test. Here is the test I wrote:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using Bunit;
    using Bunit.TestDoubles;
    using Cao.CatOs.Blazor.Pages;
    using Cao.CatOs.Blazor.Services;
    using Microsoft.AspNetCore.Authorization;
    using Microsoft.Extensions.DependencyInjection;
    using NSubstitute;
    using Volo.Abp.Authorization;
    using Volo.Abp.LanguageManagement;
    using Xunit;
    
    namespace Cao.CatOs.Blazor.Tests
    {
        public class MultilingualComponent
        {
            protected string UpdatePolicyName = LanguageManagementPermissions.LanguageTexts.Edit;
            [Fact]
            public void Should_ReturnMultilingualExportHeader_ForRenderedComponent()
            {
          
                // Arrange
                using var ctx = new TestContext();
                var authContext = ctx.AddTestAuthorization();
                authContext.SetAuthorized("admin");
                //TODO:Mock parameters for CustomLanguageService using NSubstitute
                var languageManagement = Substitute.For<ICustomLanguageTextAppService>();
                var navigationManager = Substitute.For<INavigationService>();
                var component = Substitute.For<CatOsComponentBase>();
                ctx.Services.AddSingleton(component);
                ctx.Services.AddSingleton(languageManagement);
                ctx.Services.AddSingleton(navigationManager);
                // Act
                var cut = ctx.RenderComponent<Multilingual>();
    
                // Assert
                cut.MarkupMatches("<h3>Multilingual Export</h3>");
            }
        }
    }
    

    The error occurs on the //Act line . The exception is :

    Volo.Abp.AbpException
    authorizationService should implement Volo.Abp.Authorization.IAbpAuthorizationService
       at Microsoft.AspNetCore.Authorization.AbpAuthorizationServiceExtensions.AsAbpAuthorizationService(IAuthorizationService authorizationService)
       at Microsoft.AspNetCore.Authorization.AbpAuthorizationServiceExtensions.AuthorizeAsync(IAuthorizationService authorizationService, Object resource, String policyName)
       at Microsoft.AspNetCore.Authorization.AbpAuthorizationServiceExtensions.AuthorizeAsync(IAuthorizationService authorizationService, String policyName)
       at Microsoft.AspNetCore.Authorization.AbpAuthorizationServiceExtensions.IsGrantedAsync(IAuthorizationService authorizationService, String policyName)
       at Cao.CatOs.Blazor.Pages.Multilingual.SetPermissionsAsync() in C:\CAT-OS\src\Cao.CatOs.Blazor\Pages\Multilingual.razor.cs:line 49
       at Cao.CatOs.Blazor.Pages.Multilingual.OnInitializedAsync() in C:\CAT-OS\src\Cao.CatOs.Blazor\Pages\Multilingual.razor.cs:line 38
       at Microsoft.AspNetCore.Components.ComponentBase.RunInitAndSetParametersAsync()
       at Bunit.Rendering.TestRenderer.AssertNoUnhandledExceptions() in /_/src/bunit.core/Rendering/TestRenderer.cs:line 355
       at Bunit.Rendering.TestRenderer.Render[TResult](RenderFragment renderFragment, Func`2 activator) in /_/src/bunit.core/Rendering/TestRenderer.cs:line 237
       at Bunit.Rendering.TestRenderer.RenderFragment(RenderFragment renderFragment) in /_/src/bunit.core/Rendering/TestRenderer.cs:line 55
       at Bunit.Extensions.TestContextBaseRenderExtensions.RenderInsideRenderTree(TestContextBase testContext, RenderFragment renderFragment) in /_/src/bunit.core/Extensions/TestContextBaseRenderExtensions.cs:line 45
       at Bunit.Extensions.TestContextBaseRenderExtensions.RenderInsideRenderTree[TComponent](TestContextBase testContext, RenderFragment renderFragment) in /_/src/bunit.core/Extensions/TestContextBaseRenderExtensions.cs:line 25
       at Bunit.TestContext.Render[TComponent](RenderFragment renderFragment) in /_/src/bunit.web/TestContext.cs:line 70
       at Bunit.TestContext.RenderComponent[TComponent](ComponentParameter[] parameters) in /_/src/bunit.web/TestContext.cs:line 40
       at Cao.CatOs.Blazor.Tests.MultilingualComponent.Should_ReturnMultilingualExportHeader_ForRenderedComponent() in C:\CAT-OS\Cao.CatOs.Blazor.Tests\MultilingualComponent.cs:line 38
    

    The question I have is how do I inject / mock the object Volo.Abp.Authorization.IAbpAuthorizationService, so my test picks it up? Just to be clear I am using BUnit, and my razor component inherits from the AbpComponentBase. This is why when I run the page IABPAuthorizationService exists, however in a unit test it is null.

    What I would like is an example of how to take a standard Razor componet that properly implements the ABP framework and write a unit test for it using BUnit. I am sure you will find there are quite a few items that need to be mocked and injected, in order to get it to work properly. Do you have an example I can use to follow along?

    Thanks,

    Jesse

  • 0
    maliming created
    Support Team

    We may need to rewrite some BUnit services, can you share a simple project? [email protected]

  • 0
    [email protected] created

    Thanks Maliming.... I am going to send you a test project shortly with details on what exactly is failing.

  • 0
    maliming created
    Support Team

    hi

    Please check the commit of init2.

    https://github.com/maliming/CATOSTest/commits/main

    https://github.com/maliming/CATOSTest/invitations

  • 0
    [email protected] created

    Thanks Maliming! This helped alot, and fixed my issues....

    Jesse