У меня есть простой класс, который реализует INotifyPropertyChanged
, я вызываю изменение свойства в другом потоке, и мне было довольно сложно получить FluentAsserts
, чтобы увидеть, что был вызван propertyChanged
. Кажется, это не происходит, если я использую метод Task.Delay
в методе async Task
. Но это так, если я просто сплю нитку.Fluent-ASsertions ShouldRaisePropertyChangeFor не работает для async Tasks?
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: Объект не проводится мониторинг события или уже был собран мусор. Используйте метод расширения MonitorEvents() для запуска мониторинга событий.
Я не вижу, как MonitorEvents
позаботится, если я воспользуюсь ожиданием или Thread.Sleep
. Что мне не хватает? Я получаю, что await
оставляет метод и возвращается, а Thread.Sleep
- нет.
Итак, когда он покидает TestMethod1
во время ожидания, он ударяет по объекту, который FluentAsserts
использует для отслеживания свойств? Не могли бы? Должно ли это?