Ich habe eine einfache Klasse, die INotifyPropertyChanged
implementiert, ich die Änderung der Eigenschaft auf einem anderen Thread aufrufen, und ich hatte eine ziemlich harte Zeit FluentAsserts
zu sehen, dass die propertyChanged
wurde aufgerufen. Es scheint nicht zu passieren, wenn ich eine Task.Delay
in einer async Task
Methode verwende. Aber wenn ich nur den Faden schlafe.Fluent-Assertions ShouldRaisePropertyChangeFor funktioniert nicht für asynchrone Aufgaben?
Die SimpleNotify
Klasse:
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));
}
}
}
}
}
und hier sind meine Unit-Tests:
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
}
}
}
Der genaue Fehler ist:
System.InvalidOperationException: Das Objekt ist nicht überwacht Ereignisse oder wurde bereits Müll gesammelt. Verwenden Sie die MonitorEvents() - Erweiterungsmethode, um Ereignisse zu überwachen.
Ich sehe nicht, wie MonitorEvents
würde mich interessieren, wenn ich erwarten oder Thread.Sleep
. Was vermisse ich? Ich bekomme, dass await
verlässt die Methode und kommt zurück, während Thread.Sleep
nicht.
Also, wenn es die TestMethod1
während der Wartezeit verlässt, trifft es eine Verfügung über ein Objekt, das FluentAsserts
verwendet, um die Eigenschaften zu verfolgen? Kann es? Sollte es?