2

I am trying to unit test a model decorated with NotifyPropertyChanged and DispatchMethod.

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 this test:

using NUnit.Framework;

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

}

but am getting the following error upon test execution:

System.InvalidOperationException : Instances of classes marked with DispatcherObjectAspect can only be crated on threads with synchronization contexts (typically WPF or Windows.Forms UI threads), or must implement IDispatcherObject manually.

How could I provide the required synchronization context?

4

1 回答 1

2

显然我需要做的就是设置它......

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

结案。

于 2013-10-15T20:03:48.987 回答