英文:
How to test custom validations in Blazor WASM
问题
I have a Blazor WASM and are about to write some test cases. Im new at this and wonder how I can proceed to test the component below?
public class CustomValidation : ComponentBase, IDisposable
{
private IDisposable? _subscriptions;
private EditContext? _originalEditContext;
[CascadingParameter] EditContext? CurrentEditContext { get; set; }
[Parameter] public bool DoEditValidation { get; set; } = false;
/// <inheritdoc />
protected override void OnInitialized()
{
if (CurrentEditContext == null)
{
throw new InvalidOperationException($"{nameof(DataAnnotationsValidator)} requires a cascading " +
$"parameter of type {nameof(EditContext)}. For example, you can use {nameof(DataAnnotationsValidator)} " +
$"inside an EditForm.");
}
_subscriptions = CurrentEditContext.EnableCustomValidation(DoEditValidation, true);
_originalEditContext = CurrentEditContext;
}
}
I have tried with Bunit:
public class CustomValidationTests : IDisposable
{
private CustomValidation _customValidation;
public CustomValidationTests()
{
_customValidation = new CustomValidation();
}
[Fact]
public void OnInitialized_SubscribesToCustomValidation()
{
// Arrange
using var ctx = new TestContext();
var editContext = new EditContext(new object());
// Act
var cut = ctx.RenderComponent<CustomValidation>(
builder => builder.Add(c => c.CurrentEditContext, editContext));
// Assert
Assert.NotNull(cut.Instance.CurrentEditContext);
}
}
I have tried something like this but throws an error because of CurrentEditContext protection level because it is marked with the CascadingParameter attribute.
英文:
I have a Blazor WASM and are about to write some test cases. Im new at this and wonder how I can proceed to test the component below?
public class CustomValidation : ComponentBase, IDisposable
{
private IDisposable? _subscriptions;
private EditContext? _originalEditContext;
[CascadingParameter] EditContext? CurrentEditContext { get; set; }
[Parameter] public bool DoEditValidation { get; set; } = false;
/// <inheritdoc />
protected override void OnInitialized()
{
if (CurrentEditContext == null)
{
throw new InvalidOperationException($"{nameof(DataAnnotationsValidator)} requires a cascading " +
$"parameter of type {nameof(EditContext)}. For example, you can use {nameof(DataAnnotationsValidator)} " +
$"inside an EditForm.");
}
_subscriptions = CurrentEditContext.EnableCustomValidation(DoEditValidation, true);
_originalEditContext = CurrentEditContext;
}
}
I have tried with Bunit:
public class CustomValidationTests : IDisposable
{
private CustomValidation _customValidation;
public CustomValidationTests()
{
_customValidation = new CustomValidation();
}
[Fact]
public void OnInitialized_SubscribesToCustomValidation()
{
// Arrange
using var ctx = new TestContext();
var editContext = new EditContext(new object());
// Act
var cut = ctx.RenderComponent<CustomValidation>(
builder => builder.Add(c => c.CurrentEditContext, editContext));
// Assert
Assert.NotNull(cut.Instance.CurrentEditContext);
}
}
I have tried something like this but throws and error because of CurrentEditContext protection level because it is marked with the CascadingParameter attribute.
答案1
得分: 1
Testing lifecycle methods directly is tricky, because the way they're called is controlled by the runtime. There are two ways to test the code in them:
-
直接测试生命周期方法很棘手,因为它们的调用方式由运行时控制。有两种测试其中代码的方法:
-
使用 bUnit 或任何将来出现的类似 Blazor 组件测试框架来托管和测试组件。
bUnit 不是一个完整的单元测试框架。它允许您使用您喜欢的框架,如 xUnit 或 NUnit,来测试组件。
bUnit 的首页 上显示的简单测试足以测试简单组件的正确初始化,例如:
public class MyCounterTest : TestContext
{
[Fact]
public void CounterShouldIncrementWhenClicked()
{
// Arrange: render the Counter.razor component
var cut = Render(@<Counter />);
// Act: find and click the <button> element to increment
// the counter in the <p> element
cut.Find("button").Click();
// Assert: first find the <p> element, then verify its content
cut.Find("p").MarkupMatches(@<p>Current count: 1</p>);
}
}
文档还显示了如何测试具有 参数和级联值 的组件。
给定此组件:
public class NonBlazorTypesParams : ComponentBase
{
[Parameter]
public int Numbers { get; set; }
[Parameter]
public List<string> Lines { get; set; }
}
您可以使用 RenderComponent
的 parameters
参数进行测试:
public class NonBlazorTypesParamsTest : TestContext
{
[Fact]
public void Test()
{
var lines = new List<string> { "Hello", "World" };
var cut = RenderComponent<NonBlazorTypesParams>(parameters => parameters
.Add(p => p.Numbers, 42)
.Add(p => p.Lines, lines)
);
}
}
英文:
Testing lifecycle methods directly is tricky, because the way they're called is controlled by the runtime. There are two ways to test the code in them:
- Extract the code into other methods or even classes that can be called directly and
- Use bUnit or any other similar Blazor component testing framework that appears in the future to host and test the component.
bUnit isn't a full unit testing framework. It allows you to test components using your preferred framework eg xUnit or NUnit.
The simple test shown in bUnit's landing page would be enough to test that a simple component initializes properly, eg :
public class MyCounterTest:TestContext
{
[Fact]
public void CounterShouldIncrementWhenClicked()
{
// Arrange: render the Counter.razor component
var cut = Render(@<Counter />);
// Act: find and click the <button> element to increment
// the counter in the <p> element
cut.Find("button").Click();
// Assert: first find the <p> element, then verify its content
cut.Find("p").MarkupMatches(@<p>Current count: 1</p>);
}
}
The documentation shows how to test components with Parameters and Cascading Values too.
Given this component
public class NonBlazorTypesParams : ComponentBase
{
[Parameter]
public int Numbers { get; set; }
[Parameter]
public List<string> Lines { get; set; }
}
You can test it using the parameters
argument of RenderComponent
public class NonBlazorTypesParamsTest : TestContext
{
[Fact]
public void Test()
{
var lines = new List<string> { "Hello", "World" };
var cut = RenderComponent<NonBlazorTypesParams>(parameters => parameters
.Add(p => p.Numbers, 42)
.Add(p => p.Lines, lines)
);
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论