2013-10-15 18 views
2

我想單元測試用NotifyPropertyChanged和DispatchMethod裝飾的模型。UnitTest和PostSharp工具包,域和線程

BaseModel

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Windows.Forms; 

public abstract class BaseModel : INotifyPropertyChanged, IDisposable 
{ 
    #region Fields 

    private readonly HashSet<string> ignorablePropertyNameses = new HashSet<string>(); 

    private bool isDirty; 

    #endregion 

    #region Constructors and Destructors 

    protected BaseModel() { this._propertyChanged += this.OnAnyPropertyChanged; } 

    #endregion 

    #region Public Events 

    public event PropertyChangedEventHandler PropertyChanged 
    { 
     add { this._propertyChanged += value; } 
     remove { this._propertyChanged -= value; } 
    } 

    #endregion 

    #region Events 

    private event PropertyChangedEventHandler _propertyChanged; 

    #endregion 

    #region Public Properties 

    public HashSet<string> IgnorablePropertyNames 
    { 
     get { return this.ignorablePropertyNameses; } 
    } 

    public bool IsDirty 
    { 
     get { return this.isDirty; } 
    } 

    #endregion 

    #region Public Methods and Operators 

    public void Dispose() { this._propertyChanged -= this.OnAnyPropertyChanged; } 

    public void RaisePropertyChanged(string propertyName) 
    { 
     if (null != this._propertyChanged) 
     { 
      this._propertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 

    public virtual void Save() 
    { 
     this.isDirty = false; 
     MessageBox.Show("Changes have been saved"); 
    } 

    public void SetClean() { this.isDirty = false; } 

    #endregion 

    #region Methods 

    protected void OnPropertyChanged(string propertyName) 
    { 
     PropertyChangedEventHandler handler = this._propertyChanged; 
     if (handler != null) 
     { 
      handler(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 

    private void OnAnyPropertyChanged(object sender, PropertyChangedEventArgs propertyChangedEventArgs) 
    { 
     if (!this.ignorablePropertyNameses.Contains(propertyChangedEventArgs.PropertyName)) 
     { 
      this.isDirty = true; 
     } 
    } 

    #endregion 
} 

DogModel

using System; 
using System.Threading; 

using AGP.WinForms.MVC.PassiveView; 

using PostSharp.Toolkit.Domain; 
using PostSharp.Toolkit.Threading; 

[NotifyPropertyChanged] 
public class DogModel : BaseModel 
{ 
    #region Fields 

    private Timer timer; 

    #endregion 

    #region Constructors and Destructors 

    public DogModel() 
    { 
     this.IgnorablePropertyNames.Add("CurrentDateAndTime"); 
     this.timer = new Timer(state => this.BroadcastTime(), null, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1)); 
    } 

    #endregion 

    #region Public Properties 

    public string Breed { get; set; } 

    public DateTime CurrentDateAndTime { get; set; } 
    public string Name { get; set; } 

    #endregion 

    #region Methods 

    [DispatchedMethod] 
    private void BroadcastTime() { this.CurrentDateAndTime = DateTime.Now; } 

    #endregion 
} 

使用這個測試:

using NUnit.Framework; 

[TestFixture] 
public class DogModelTests 
{ 
    [Test] 
    public void DirtyFlag() 
    { 
     var model = new DogModel(); 
     Assert.IsFalse(model.IsDirty); 
    } 

} 

但我得到在測試執行以下錯誤:

System.InvalidO perationException:標記爲DispatcherObjectAspect的類的實例只能在具有同步上下文的線程上(通常爲WPF或Windows.Forms UI線程)進行創建,或者必須手動實現IDispatcherObject。

我該如何提供所需的同步上下文?

回答

1

顯然,所有我需要做的是將它設置...

[SetUp] 
    public void SetUp() 
    { 
     SynchronizationContext.SetSynchronizationContext(new SynchronizationContext()); 
    } 

結案。