【问题标题】:Unit Testing a Blazor RenderFragment element对 Blazor RenderFragment 元素进行单元测试
【发布时间】:2020-05-12 17:28:34
【问题描述】:

我已经开始编写一个动态构建 RenderFragment 元素的方法。因此,我也尝试在方法旁边编写单元测试。

我从一个非常基本的元素开始,但它失败了。这是正在测试的具体方法:

public RenderFragment buildFragment(string element, string elementContent, string[] attribute, string[] attributeContent)
    {
        RenderFragment content = builder => {
            builder.OpenElement(0, element);
            if (attribute != null)
            {
                for (int i = 0; attribute.Length - 1 >= i; ++i)
                {
                    builder.AddAttribute(0, attribute[i], attributeContent[i]);
                }
            }
            if (!string.IsNullOrEmpty(elementContent))
            {
                builder.AddContent(0, elementContent);
            }
            builder.CloseElement();
        };

        return content;
    }

这是我对使用 xUnit 的方法的第一个基本测试:

public void BuildFragmentReturnsOneElement()
        {
            //Arrange
            RenderFragment fragment = builder =>
            {
                builder.OpenElement(0, "p");
                builder.CloseElement();
            };

            //Act
            RenderFragment result = _dynamicContentHelper.buildFragment("p", string.Empty, null, null);

            //Assert
            Assert.Same(fragment, result);
        }

我收到的错误是:

消息:Assert.Same() 失败 预期:RenderFragment { Method = Void b__2_0(Microsoft.AspNetCore.Blazor.RenderTree.RenderTreeBuilder), Target = c { } } 实际:RenderFragment { Method = Void b__0(Microsoft.AspNetCore.Blazor.RenderTree.RenderTreeBuilder), Target = c__DisplayClass0_0 { attribute = null, attributeContent = null, element = "p", elementContent = "" } }

我不明白为什么 fragment 对象上的 Targetresult 上的 Target 不同。

【问题讨论】:

    标签: c# xunit blazor


    【解决方案1】:

    RenderFragment 是一个委托方法,所以当你编写这样的代码时:

    RenderFragment fragment = builder =>
                {
                    builder.OpenElement(0, "p");
                    builder.CloseElement();
                };
    

    您不是在创建物化工件,而是声明一个可以调用的委托。

    因此,代码Assert.Same(fragment, result); 正在比较两个委托,这显然不相同——它们指向两个不同的方法。

    我认为您应该调查 Blazor 源的“测试”文件夹

    This section may help a lot

    他们应用的技术是检查渲染树的帧

    // Act
    var frames = GetRenderTree(component);
    
    // Assert
    Assert.Collection(
     frames,
     frame => AssertFrame.Component(frame, "Test.RenderChildContent", 2, 0),
     frame => AssertFrame.Attribute(frame, RenderTreeBuilder.ChildContent, 1),
     frame => AssertFrame.Markup(frame, "\n  <div></div>\n", 2));
    

    Also, this section with a TestRenderer 里面有这段代码

    protected RenderTreeFrame[] GetRenderTree(IComponent component)
            {
                var renderer = new TestRenderer();
                renderer.AttachComponent(component);
                component.SetParameters(ParameterCollection.Empty);
                return renderer.LatestBatchReferenceFrames;
            }
    

    看看他们是如何进行测试的,因为我无法在这里全部重现,但这些是关键......

    【讨论】:

      【解决方案2】:

      我发现有一个用于单元测试 Blazor 组件的非常有用的库,名为 bUnit library。测试编写起来非常简单。这是一个验证按钮单击是否有效的示例。

      [Fact]
      public void TestCounter()
      {
          // Arrange
          var cut = RenderComponent<Counter>();
          cut.Find("p").MarkupMatches("<p>Current count: 0</p>");
      
          // Act
          var element = cut.Find("button");
          element.Click();
      
          //Assert
          cut.Find("p").MarkupMatches("<p>Current count: 1</p>");
      }
      

      这是另一个示例,其中包括使用 JustMock Lite 模拟服务

      [Fact]
      public void TestFetchData_ForecastIsNull()
      {
          // Arrange
          var weatherForecastServiceMock = Mock.Create<IWeatherForecastService>();
          Mock.Arrange(() => weatherForecastServiceMock.GetForecastAsync(Arg.IsAny<DateTime>()))
              .Returns(new TaskCompletionSource<WeatherForecast[]>().Task);
          Services.AddSingleton<IWeatherForecastService>(weatherForecastServiceMock);
      
          // Act
          var cut = RenderComponent<FetchData>();
      
          // Assert - that it renders the initial loading message
          var initialExpectedHtml = 
                      @"<h1>Weather forecast</h1>
                      <p>This component demonstrates fetching data from a service.</p>
                      <p><em>Loading...</em></p>";
          cut.MarkupMatches(initialExpectedHtml);
      }
      

      示例来自博文Unit Testing Blazor Components with bUnit and JustMock

      【讨论】:

        猜你喜欢
        • 2018-05-27
        • 2012-01-08
        • 2019-11-02
        • 1970-01-01
        • 1970-01-01
        • 2012-05-14
        • 2023-03-21
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多