我有一個Search組件,它實作了一個退避計時器,因此它不會呼叫ValueChanged(因此不會立即更新與之相關的屬性)。
我的問題
bUnit 測驗似乎并沒有雙向系結我正在更新的值。測驗代碼
private string StringProperty { get; set; }
[Fact] 。
public async Task AfterDebounce_ValueUpdates()
{
var myString = ""。
var cut = RenderComponent<Search> (parameters => parameters
.Add(p => p.Value, StringProperty)
.Add(p => p.ValueChanged, (s) => myString = s)
);
var input = cut.Find("input"/span>)。
input.Input("單元測驗")。
Assert.Equal("unit test", cut.Instance.Value)。
Assert.NotEqual("unit test", myString)。
//Assert.NotEqual("unit test", StringProperty);/span>
await Task.Delay(5000)。
Assert.Equal("單元測驗", myString)。
//Assert.Equal("unit test", StringProperty);。
我本以為注釋出來的部分會起作用(因為它們做的是與ValueChanged相同的事情,以更新屬性),但它們失敗了。
組件
public class Search : ComponentBase
{
[Parameter] public string? Value { get; set; }
[Parameter] public EventCallback<string> ValueChanged { get; set; }
[DisallowNull] public ElementReference? Element { get; protected set; }
private System.Timers.Timer timer = null;
protected string? CurrentValue {
get => Value;
set {
var hasChanged = !EqualityComparer<string>.Default.Equals(value, Value) 。
if (hasChanged)
{
Value = value;
DisposeTimer()。
timer = new System.Timers.Timer(350)。
timer.Elapsed = TimerElapsed_TickAsync;
timer.Enabled = true;
Timer.Start();
}
}
}
private void DisposeTimer()
{
if (timer != null)
{
timer.Enabled = false;
timer.Elapsed -= TimerElapsed_TickAsync;
timer.Dispose()。
timer = null;
}
}
private async void TimerElapsed_TickAsync()
object sender,
EventArgs e)。
{
await ValueChanged.InvokeAsync(Value)。
}
protected override void BuildRenderTree(RenderTreeBuilder builder)
{
builder.OpenElement(10, "input") 。
builder.AddAttribute(20, "type", "text") 。
builder.AddAttribute(60, "value", BindConverter.FormatValue(CurrentValue))。
builder.AddAttribute(70, "oninput", EventCallback.Factory. CreateBinder<string?>(this, __value => CurrentValue = __value, CurrentValue)。
builder.AddElementReferenceCapture(80, __inputReference => Element = __inputReference);
builder.CloseElement()。
}
}
它是如何被使用的:
它可以像這樣使用,每當Query被更新時,網格就會更新。
<Search @bind-Value=Query />
<Grid Query=@Query />
@code {
private string? Query { get; set; }
}
這在實踐中運行良好,但在測驗時我遇到了問題。
uj5u.com熱心網友回復:
我在我的機器上進行了本地嘗試,測驗通過了。
這是你的組件的簡化版本,它只在每次數值變化時呼叫TimerElapsed_TickAsync,而不是在每次定時器耗盡時呼叫(AutoReset默認為true),還有兩種不同的測驗撰寫方式,在我的機器上都通過了:
public class Search 。ComponentBase, IDisposable private readonly Timer定時器。
[] public string? Value { get; set; }
[] public EventCallback<string> ValueChanged { get; set; }
[] public ElementReference? Element { get; protected set; }
public Search()
{
timer = new Timer(350)。
timer.Elapsed = TimerElapsed_TickAsync;
timer.Enabled = true;
timer.AutoReset = false;
}
protected string? 當前值
{
get => Value;
set
{
var hasChanged = !EqualityComparer<string>.Default.Equals(value, Value) 。
if (hasChanged)
{
RestartTimer();
Value = value;
}
}
}
private void RestartTimer()。
{
if (timer.Enabled)
Timer.Stop()。
Timer.Start()。
}
private void TimerElapsed_TickAsync(object sender, e)?
=> ValueChanged.InvokeAsync(Value)。
protected override void BuildRenderTree(RenderTreeBuilder builder)
{
builder.OpenElement(10, "input") 。
builder.AddAttribute(20, "type", "text") 。
builder.AddAttribute(60, "value", BindConverter.FormatValue(CurrentValue))。
builder.AddAttribute(70, "oninput", EventCallback.Factory. CreateBinder<string?>(this, __value => CurrentValue = __value, CurrentValue)。
builder.AddElementReferenceCapture(80, __inputReference => Element = __inputReference);
builder.CloseElement()。
}
public void Dispose() => timer.Dispose();
}
而C#版本的測驗:
[Fact]
public async Task AfterDebounce_ValueUpdates()
{
var expected = "test input"/span>;
var count = 0;
var value = ""/span>;
var cut = RenderComponent<Search> (parameters => parameters
.Add(p => p.Value, value)
.Add(p => p.ValueChanged, (s) =>
{
value = s;
count ;
})
);
cut.Find("input").Input(expected)。
await Task.Delay(350)。
Assert.Equal(1, count)。
Assert.Equal(expected, value)。
}
以及測驗的.razor版本(也就是寫在.razor檔案中):
@inherits TestContext
@code
{
[事實]
public async Task AfterDebounce_ValueUpdates()
{
var expected = "test input";
var value = ""。
var cut = Render(@<Search @bind-Value="value" /> ) 。
cut.Find("input").Input(expected);
await Task.Delay(350);
Assert.Equal(expected, value);
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/310308.html
標籤:
上一篇:Jasmine測驗--附著元素的持久性以及為什么點擊會觸發不止一次
下一篇:如何在DjangoRESTAPI端點上寫一個單元測驗,該端點有permission_classes=(IsAuthenticated,)
