gpt4 book ai didi

c# - Fluent-ASertions ShouldRaisePropertyChangeFor 不适用于异步任务?

转载 作者:行者123 更新时间:2023-11-30 20:32:48 24 4
gpt4 key购买 nike

我有一个实现 INotifyPropertyChanged 的简单类,我在另一个线程上调用属性更改,我很难让 FluentAsserts 看到 propertyChanged 被调用。如果我在 async Task 方法中使用 Task.Delay 似乎不会发生这种情况。但如果我只是让线程休眠,它就会起作用。

SimpleNotify 类:

namespace FluentAssertPropertyThreads
{
class SimpleNotify : System.ComponentModel.INotifyPropertyChanged
{
public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
private void onChange(string name)
{
this.PropertyChanged?.Invoke(this, new System.ComponentModel.PropertyChangedEventArgs(name));
}

private int count = 0;
public int Count
{
get
{
return this.count;
}

set
{
if (this.count != value)
{
this.count = value;
this.onChange(nameof(this.Count));
}
}
}
}
}

这是我的单元测试:

using FluentAssertions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Threading;
using System.Threading.Tasks;

namespace FluentAssertPropertyThreads
{
[TestClass]
public class UnitTest1
{
private SimpleNotify simpleNotify;
private int notifyCount;
private void bumpCount()
{
this.simpleNotify.Count++;
}

private void SimpleNotify_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
SimpleNotify simpleNotify = sender as SimpleNotify;
if (simpleNotify == null)
{
throw new ArgumentNullException(nameof(sender), "sender should be " + nameof(SimpleNotify));
}

if (e.PropertyName.Equals(nameof(SimpleNotify.Count), StringComparison.InvariantCultureIgnoreCase))
{
this.notifyCount++;
}
}

[TestInitialize]
public void TestSetup()
{
this.notifyCount = 0;
this.simpleNotify = new SimpleNotify();
this.simpleNotify.PropertyChanged += SimpleNotify_PropertyChanged;
this.simpleNotify.MonitorEvents();

Thread thread = new Thread(this.bumpCount)
{
IsBackground = true,
Name = @"My Background Thread",
Priority = ThreadPriority.Normal
};
thread.Start();
}

[TestMethod]
public async Task TestMethod1()
{
await Task.Delay(100);
this.notifyCount.Should().Be(1); //this passes, so I know that my notification has be executed.
this.simpleNotify.ShouldRaisePropertyChangeFor(x => x.Count); //but this fails, saying that I need to be monitoring the events (which I am above)
}

[TestMethod]
public void TestMethod2()
{
Thread.Sleep(100);
this.notifyCount.Should().Be(1); //this passes, so I know that my notification has be executed.
this.simpleNotify.ShouldRaisePropertyChangeFor(x => x.Count); //this passes as I expected
}
}
}

准确的错误是:

System.InvalidOperationException: Object is not being monitored for events or has already been garbage collected. Use the MonitorEvents() extension method to start monitoring events.

如果我使用 await 或 Thread.Sleep,我不明白 MonitorEvents 会如何关心。我错过了什么?我知道 await 离开方法并返回,而 Thread.Sleep 没有。

因此,当它在等待期间离开 TestMethod1 时,它正在对 FluentAsserts 用于跟踪属性的对象进行处置?可以吗?应该是?

最佳答案

是的,就像你说的那样:await 暂停当前方法的执行并创建一个状态机以在 Delay 完成后返回到该方法。但是调用者(一个 UnitTest 引擎)并不期望您的测试是异步的,而是简单地结束了执行,这导致了对象的处置。

Stephen Cleary 写了一篇精彩的文章 MSDN article about Unit testing and async/await keywords ,您可能应该将代码移出到返回 Task 的方法中,并在测试中等待所有这些,如下所示:

async Task Testing()
{
await Task.Delay(100);
this.notifyCount.Should().Be(1);
this.simpleNotify.ShouldRaisePropertyChangeFor(x => x.Count);
}

[TestMethod]
public async Task TestMethod1()
{
await Testing();
}

但这仍然可能会失败,因为 await 之后的逻辑可能会在一次性处理后执行。

关于c# - Fluent-ASertions ShouldRaisePropertyChangeFor 不适用于异步任务?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40896183/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com