代码之家  ›  专栏  ›  技术社区  ›  isxpjm

我们如何在Blazor Bunit单元测试中调用调用StateHasChanged的方法

  •  0
  • isxpjm  · 技术社区  · 2 年前

    考虑以下Blazor组件:

    @page "/"
    <p id="message">@message</p>
    
    @code {
    
        string message = "Hello!";
    
        public Task UpdateMessage(string newMessage)
        {
            message = newMessage;
            StateHasChanged();
            return Task.CompletedTask;
        }
    }
    

    Bunit测试该单元测试上述代码:

    using Bunit;
    
    namespace BlazorTest.Client.Tests
    {
        public class IndexTests : TestContext
        {
            [Fact]
            public async Task MessageIsUpdated()
            {
                var component = RenderComponent<Pages.Index>();
                Assert.Equal("Hello!", component.Find("#message").TextContent);
                await component.Instance.UpdateMessage("Hello world!");
                Assert.Equal("Hello world!", component.Find("#message").TextContent);
            }
        }
    }
    

    这引发了一个异常:

     System.InvalidOperationException
     The current thread is not associated with the Dispatcher. Use InvokeAsync() to switch execution to the Dispatcher when triggering rendering or component state.
    

    请帮我解释一下这个错误的含义,以及如何修复它,以便我可以对功能进行单元测试?

    2 回复  |  直到 2 年前
        1
  •  3
  •   jrummell    2 年前
    [Fact]
    public async Task MessageIsUpdated()
    {
        var component = RenderComponent<Pages.Index>();
        Assert.Equal("Hello!", component.Find("#message").TextContent);
        await component.InvokeAsync(() => component.Instance.UpdateMessage("Hello world!"));
        Assert.Equal("Hello world!", component.Find("#message").TextContent);
    }
    
        2
  •  1
  •   Henk Holterman    2 年前

    首先,示例方法并不真正需要StateHasChanged(),但对于这个问题,它是可以的。

    我不知道如何使用正确的Sync上下文执行测试,但您可以调整代码:

    public Task UpdateMessage(string newMessage)
    {
        message = newMessage;
        return InvokeAsync(StateHasChanged);
        //return Task.CompletedTask;
    }
    

    或者使用async&等候

    public async Task UpdateMessage(string newMessage)
    {
        message = newMessage;
        await InvokeAsync(StateHasChanged);
    }