You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何对包含OnPropertyChanged()的ViewModel Setter进行单元测试?

测试ViewModel的Setter与PropertyChanged事件

我正在测试一个包含Getter和Setter的ViewModel,其基类为ObservableObject,且Setter中调用了OnPropertyChanged()。不清楚如何测试该Setter,以验证值是否已设置以及PropertyChanged事件是否触发,希望能得到相关示例。

我的ViewModel代码

public class ViewModel : ObservableObject
{
    private Connection _connection;
       
    public string ConnectionName 
    { 
        get { return _connection.ConnectionName; } 
        set { _connection.ConnectionName = value; OnPropertyChanged(); } 
    }
          
    public ViewModel(Connection connection)
    {
        _connection = connection;
    }
}

参考的INotifyPropertyChanged测试示例

GroupViewModel实现

class GroupViewModel : INotifyPropertyChanged
{
    public GroupViewModel()
    {        
    }

    private ObservableCollection<Group> _groupList;

    public ObservableCollection<Group> GroupList
    {
        get { return _groupList; }

        set
        {
            _groupList = value;
            NotifyPropertyChanged("GroupList");
        }
    }

    private void NotifyPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

GroupViewModel测试代码

public class GroupViewModelTests
{
    [TestMethod()]
    public void TestGroupList()
    {
        List<Group> listOfGroups = new List<Group>();
        Group Group = new Group();
        listOfGroups.Add(Group);

        bool didFire = false;
        GroupViewModel _viewModel = new GroupViewModel();
        ObservableCollection<Group> _groupList = new ObservableCollection<Group>(listOfGroups);

        _viewModel.PropertyChanged += (s, e) =>
        {
            didFire = true;
            Assert.AreEqual("GroupList", e.PropertyName);
            Assert.AreEqual(true, _viewModel.GroupList.Equals(_groupList));
        };

        _viewModel.GroupList = _groupList;
        Assert.IsTrue(didFire);
    }
}

针对你的ViewModel的测试示例

因为你的ViewModel依赖Connection对象,测试时可以先创建一个Connection实例(或用模拟框架如Moq生成假对象),然后订阅PropertyChanged事件,验证Setter的行为:

public class ViewModelTests
{
    [TestMethod]
    public void ConnectionName_SetValue_TriggersPropertyChangedAndUpdatesConnection()
    {
        // 准备测试数据
        var testConnection = new Connection { ConnectionName = "初始名称" };
        var viewModel = new ViewModel(testConnection);
        bool propertyChangedFired = false;
        string changedPropertyName = string.Empty;
        string testNewName = "新连接名称";

        // 订阅PropertyChanged事件
        viewModel.PropertyChanged += (sender, e) =>
        {
            propertyChangedFired = true;
            changedPropertyName = e.PropertyName;
        };

        // 执行Setter操作
        viewModel.ConnectionName = testNewName;

        // 验证结果
        Assert.IsTrue(propertyChangedFired, "PropertyChanged事件未触发");
        Assert.AreEqual(nameof(ViewModel.ConnectionName), changedPropertyName, "触发事件的属性名称不正确");
        Assert.AreEqual(testNewName, testConnection.ConnectionName, "Connection对象的ConnectionName未被更新");
        Assert.AreEqual(testNewName, viewModel.ConnectionName, "ViewModel的ConnectionName属性值不正确");
    }
}

// 假设Connection类定义如下(如果实际结构不同,调整测试中的对应部分即可)
public class Connection
{
    public string ConnectionName { get; set; }
}

测试关键点说明

  • 依赖处理:通过传入真实或模拟的Connection对象,确保ViewModel的依赖可控制
  • 事件订阅:在设置属性前订阅PropertyChanged,记录事件触发状态和属性名
  • 多重验证:不仅验证事件是否触发,还要确认属性值是否同步更新到底层Connection对象,以及ViewModel的Getter返回正确值

内容的提问来源于stack exchange,提问作者Ming

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 09:55:35