【问题标题】:How do I unit test errors in an IDataErrorInfo business object?如何对 IDataErrorInfo 业务对象中的错误进行单元测试?
【发布时间】:2010-02-26 14:45:27
【问题描述】:

我正在为 WPF 应用程序编写(尝试编写)单元测试。

UI 绑定以实现 IDataErrorInfo 的业务对象,这样当我在我的视图 xaml 中设置 ValidatesOnDataErrors=True 时,只要调用绑定业务对象的设置器,就会调用错误索引器 (this[])。 这部分很棒。

现在,如果我从 unitTest 调用相同属性的设置器,它永远不会调用错误索引器。如何强制从单元测试中评估 IDataErrorInfo 索引器?

只是为了说明,这是我的一个简单的错误索引器,它包含一个 Name 属性。设置'myObject.Name = string.Empty;'当我在单元测试中这样做时,确实调用了设置器,但不调用错误索引器。

        public string Name
    {
        get { return _name; }
        set
        {
            _name = value;
            IsDirty = true;
            OnPropertyChanged("Name");
        }
    }

        #region IDataErrorInfo

    public Dictionary<string, string> ErrorCollection;

    public string this[string property]
    {
        get
        {
            string msg = null;
            switch (property)
            {
                case "Name":
                    if (string.IsNullOrEmpty(Name))
                        msg = "ICU Name is required.";
                    else if (Name.Length < 4)
                        msg = "ICU Name must contain at least 4 characters.";
                    else if (_parent.Units.AsEnumerable().Count(u => u.Name == Name) > 1)
                        msg = Name + " already exists, please change to a different Name.";
                    break;
            }


            if (msg != null && !ErrorCollection.ContainsKey(property))
                ErrorCollection.Add(property, msg);
            if (msg == null && ErrorCollection.ContainsKey(property))
                ErrorCollection.Remove(property);

            return msg;
        }
    }

    public string Error
    {
        get { return null; }
    }
    #endregion

谢谢!

【问题讨论】:

    标签: wpf unit-testing idataerrorinfo


    【解决方案1】:

    您需要自己挂钩PropertyChanged 事件,然后在调用您的处理程序时,使用属性名称调用索引器。或者不要挂钩事件并使用您正在测试的属性的名称调用索引器。

    这就是 .NET 所做的。它使用属性名称调用索引器。

    MyClass mc = new MyClass();
    mc.Name = "abc";
    string error = mc["Name"];
    

    【讨论】:

      【解决方案2】:

      我在单元测试中要做的是设置 Name 的值,然后显式调用索引器来检查错误。

      您可以在单元测试中挂钩 PropertyChanged 事件,但我认为这没有意义,因为您必须以某种方式通知测试方法该事件已收到,然后您必须调用无论如何索引器。

      【讨论】:

      • 是的,您和 Joel B Fant 的方法都非常有效。通过调用索引器而不是挂钩 PropertyChanged 事件来减少嘲笑。谢谢大家。
      【解决方案3】:

      以下 NUnit 测试调用 Name 属性的索引器并验证错误消息。

      [TestFixture]
      public class MyClassTests
      {
          [TestCase("", "ICU Name is required.")]
          [TestCase("A Valid Name", null)]
          public void ValidationIcuNameIsRequired(string name, string expectedResult)
          {
              // Arrange 
              var systemUnderTest = new MyClass();
      
              // Act
              systemUnderTest.Name = name;
      
              // Assert
              Assert.AreEqual(expectedResult, systemUnderTest[nameof(systemUnderTest.Name)]);
          }
      
          [TestCase("a", "ICU Name must contain at least 4 characters.")]
          [TestCase("ab", "ICU Name must contain at least 4 characters.")]
          [TestCase("abc", "ICU Name must contain at least 4 characters.")]
          [TestCase("abcd", null)]
          [TestCase("abcde", null)]
          public void ValidationIcuNameLongerThanThreeCharacters(string name, string expectedResult)
          {
              // Arrange 
              var systemUnderTest = new MyClass();
      
              // Act
              systemUnderTest.Name = name;
      
              // Assert
              Assert.AreEqual(expectedResult, systemUnderTest[nameof(systemUnderTest.Name)]);
          }
      
          [Test]
          public void ValidationParentDoesNotExist()
          {
              // Arrange
              var systemUnderTest = new MyClass();
              string icuName = "TestName";            
              systemUnderTest.Parent.Units.Add(new Unit() {Name = icuName });
      
              // Act
              systemUnderTest.Name = icuName;
      
              // Assert
              Assert.AreEqual(icuName + " already exists, please change to a different Name.", systemUnderTest[nameof(systemUnderTest.Name)]);
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-06-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-04-15
        • 2010-09-11
        • 2021-12-22
        • 2018-10-28
        相关资源
        最近更新 更多