문제

I am writing (attempting to write) unit tests for a WPF application.

The business objects that the UI binds to implement IDataErrorInfo, such that when I set ValidatesOnDataErrors=True in my View xaml, the error indexer (this[]) is called anytime the setter for the bound business object is called. That part is great.

Now if I call that same property's setter from a unitTest, it never calls the error indexer. How do I force the IDataErrorInfo indexer to be evaluated from within a unit test?

just for illustration, here is one of my simple error indexers that contains a Name property. Setting 'myObject.Name = string.Empty;' does call the setter, but not the error indexer when I do this in my unit tests.

        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

Thanks!

도움이 되었습니까?

해결책

버전 2.1.0-M1 이후, Maven은 pom.xml에서 빌드 타임 스탬프를 얻으려면 특별 구문을 지원하고 doc 여기가 있습니다 :

<project>
  ...
  <properties>
    <maven.build.timestamp.format>yyyyMMdd.HHmmss</maven.build.timestamp.format>
  </properties>
  ...
</project>
.

또는 "nofollow"> BuildNumber-Maven-Plugin .

다른 팁

You need to hook into the PropertyChanged event yourself and then when your handler is called, call the indexer with the property name. Or don't hook into the event and call the indexer with the name of the property you're testing.

That's what .NET does. It calls the indexer with property names.

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

The following NUnit tests called the indexer for the Name property and validate the Error message.

[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)]);
    }
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top