英文:
bUnit not updating bound property
问题
I wrote a Blazor Client component which I'm trying to test using a bUnit .razor test.
The component contains a text input that is bound to a MyValue
property. The input listens to @onkeyup
event and adds the MyValue
value to a List when Enter key is pressed.
The input element looks like this:
<input type="text" @bind-value="MyValue" @bind-value:event="onchange" @onkeyup="InputOnKeyUp"/>
The InputOnKeyUp
handler looks like this:
private void InputOnKeyUp(KeyboardEventArgs e)
{
if (e.Code == "Enter" || e.Code == "NumpadEnter")
{
var trimmed = MyValue.Trim();
if (!model.MyList.Contains(trimmed) && !string.IsNullOrEmpty(trimmed))
model.MyList.Add(trimmed);
MyValue = "";
}
}
I am accessing the input element in the bUnit test with .Find
function, like so:
var textBox = cut.Find("input");
When passing keys from bUnit, the MyValue
property, which the input is bound to, doesn't get updated, even though the application works as expected. I am passing the keys like so:
var textBox = cut.Find("input");
textBox.KeyUp("v");
textBox.KeyUp("a");
textBox.KeyUp("l");
textBox.KeyUp(Key.Space);
textBox.KeyUp("1");
I saw here that I should use the change event, but I need access to the key that is pressed, so I can't go that way.
[EDIT] I'm including the entire test file:
@code {
public void HappyPath()
{
using var ctx = new TestContext();
ctx.Services.AddScoped<IJsApiService, JsApiService>();
var values = new List<string>();
var cut = ctx.Render(@<MyComponent MyValues="values"/>);
cut.Find(".mud-chip-content").TextContent.Should().Be("val 1");
var textBox = cut.Find("input");
textBox.KeyUp("v");
textBox.KeyUp("a");
textBox.KeyUp("l");
textBox.KeyUp(Key.Space);
textBox.KeyUp("2");
textBox.KeyUp(Key.Enter);
var chips = cut.FindAll(".mud-chip-content");
chips.Count.Should().Be(2);
chips.Last().TextContent.Should().Be("val 2");
values.Count.Should().Be(2);
values.Last().Should().Be("val 2");
cut.Find(".mud-chip-close-button").Click();
chips.Count.Should().Be(1);
cut.Find(".mud-chip-content").TextContent.Should().Be("val 2");
values.Count Should().Be(1);
values.First().Should().Be("val 2");
}
}
Any solutions?
英文:
I wrote a Blazor Client component which I'm trying to test using a bUnit .razor test.
The component contains a text input that is bound to a MyValue
property. The input listens to @onkeyup
event and adds the MyValue
value to a List when Enter key is pressed.
The input element looks like this:
<input type="text" @bind-value="MyValue" @bind-value:event="onchange" @onkeyup="InputOnKeyUp"/>
The InputOnKeyUp
handler looks like this:
private void InputOnKeyUp(KeyboardEventArgs e)
{
if (e.Code == "Enter" || e.Code == "NumpadEnter")
{
var trimmed = MyValue.Trim();
if (!model.MyList.Contains(trimmed) && !string.IsNullOrEmpty(trimmed))
model.MyList.Add(trimmed);
MyValue = "";
}
}
I am accessing the input element in the bUnit test with .Find
function, like so:
var textBox = cut.Find("input");
When passing keys from bUnit, the MyValue
property, which the input is bound to, doesn't get updated, even though the application works as expected. I am passing the keys like so:
var textBox = cut.Find("input");
textBox.KeyUp("v");
textBox.KeyUp("a");
textBox.KeyUp("l");
textBox.KeyUp(Key.Space);
textBox.KeyUp("1");
I saw here that I should use the change event, but I need access to the key that is pressed, so I can't go that way.
[EDIT] I'm including the entire test file:
@code {
public void HappyPath()
{
using var ctx = new TestContext();
ctx.Services.AddScoped<IJsApiService, JsApiService>();
var values = new List<string>();
var cut = ctx.Render(@<MyComponent MyValues="values"/>);
cut.Find(".mud-chip-content").TextContent.Should().Be("val 1");
var textBox = cut.Find("input");
textBox.KeyUp("v");
textBox.KeyUp("a");
textBox.KeyUp("l");
textBox.KeyUp(Key.Space);
textBox.KeyUp("2");
textBox.KeyUp(Key.Enter);
var chips = cut.FindAll(".mud-chip-content");
chips.Count.Should().Be(2);
chips.Last().TextContent.Should().Be("val 2");
values.Count.Should().Be(2);
values.Last().Should().Be("val 2");
cut.Find(".mud-chip-close-button").Click();
chips.Count.Should().Be(1);
cut.Find(".mud-chip-content").TextContent.Should().Be("val 2");
values.Count.Should().Be(1);
values.First().Should().Be("val 2");
}
}
Any solutions?
答案1
得分: 3
The KeyUp
method of bUnit will just invoke your onkeyup
event that is attached to your input
element. It will not enter the characters one-by-one like an end-to-end testing framework like playwright.
Therefore you have to go with the approach, as you already mentioned, of using Change
:
// Arrange
var textBox = cut.Find("input");
textBox.Change("val 1");
// Act
textBox.KeyUp(Key.Enter);
// Assert
AssertMyValueIsInModel();
At least from the code you provided your onkeyup
doesn't have any other side-effects. So the given code will put the "val 1" into the input box that is bound to MyValue
and when we raise the onkeyup
event, we'll add the value to the model's list.
英文:
The KeyUp
method of bUnit will just invoke your onkeyup
event that is attached to your input
element. It will not enter the characters one-by-one like an end-to-end testing framework like playwright.
Therefore you have to go with the approach, as you already mentioned, of using Change
:
// Arrange
var textBox = cut.Find("input");
textBox.Change("val 1");
// Act
textBox.KeyUp(Key.Enter);
// Assert
AssertMyValueIsInModel();
At least from the code you provided your onkeyup
doesn't have any other side-effects. So the given code will put the "val 1" into the input box that is bound to MyValue
and when we raise the onkeyup
event, we'll add the value to the model's list.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论