在使用WPF的MVVM中,如何单元测试ViewModel和View之间的链接 - 代码日志

在使用WPF的MVVM中,如何单元测试ViewModel和View之间的链接

在MVVM中,通过数据绑定将View连接到ViewModel是正常的。

因此,如果一个属性的名称在数据绑定的一个Model对象上发生变化,那么就没有编译错误。

当编译器不会停止一个bug时,我想到的下一件事是“UnitTest”,但是

How do you unit test this without
spending forever writing a GUI test?

是否有一个系统将检查所有绑定的属性是否有效(无需运行UI),我可以在单元测试中调用?

我正在寻找一些会采取视图的东西,然后循环所有WPF控件,对于每个WPF控件,它将查看所​​有绑定并检查它们是否有效。

顺便说一下,有关如何使OnPropertyChanged安全,和/或如何测试它的一些很好的问题(但是这些都完成了WPF视图的级别)。

> How to make Databinding type safe and support refactoring
> Automatically INotifyPropertyChanged
> workarounds for nameof() operator in C#: typesafe databinding
> A Fluent Interface For Testing INotifyPropertyChanged
> Automatic Class Tester将测试所有简单的proptites和INotifyPropertyChanged

我对这个问题给予了赏识,因为有人必须对这个问题进行思考,并提出解决方案。

我想我已经提出了一些可以使用简单的反思工作的东西,并调整过去使用过的一些代码(FindBindingsRecursively方法的代码是由Martin Bennedik作为他Enterprise WPF Validation Control的一部分编写的):

[TestMethod]
public void CheckWpfBindingsAreValid()
{
    // instansiate the xaml view and set DataContext
    var yourView = new YourView(); 
    yourView.DataContext = YourViewModel;

    FindBindingsRecursively(yourView,
            delegate(FrameworkElement element, Binding binding, DependencyProperty dp)
            {
                var type = yourView.DataContext.GetType();

                // check that each part of binding valid via reflection
                foreach (string prop in binding.Path.Path.Split('.'))
                {
                    PropertyInfo info = type.GetProperty(prop);
                    Assert.IsNotNull(info);
                    type = info.PropertyType;
                }
    });
}

private delegate void FoundBindingCallbackDelegate(FrameworkElement element, Binding binding, DependencyProperty dp);

private void FindBindingsRecursively(DependencyObject element, FoundBindingCallbackDelegate callbackDelegate)
{
    // See if we should display the errors on this element
    MemberInfo[] members = element.GetType().GetMembers(BindingFlags.Static |
                BindingFlags.Public |
                BindingFlags.FlattenHierarchy);

    foreach (MemberInfo member in members)
    {
        DependencyProperty dp = null;

        // Check to see if the field or property we were given is a dependency property
        if (member.MemberType == MemberTypes.Field)
        {
            FieldInfo field = (FieldInfo)member;
            if (typeof(DependencyProperty).IsAssignableFrom(field.FieldType))
            {
                dp = (DependencyProperty)field.GetValue(element);
            }
        }
        else if (member.MemberType == MemberTypes.Property)
        {
            PropertyInfo prop = (PropertyInfo)member;
            if (typeof(DependencyProperty).IsAssignableFrom(prop.PropertyType))
            {
                dp = (DependencyProperty)prop.GetValue(element, null);
            }
        }

        if (dp != null)
        {
            // Awesome, we have a dependency property. does it have a binding? If yes, is it bound to the property we're interested in?
            Binding bb = BindingOperations.GetBinding(element, dp);
            if (bb != null)
            {
                // This element has a DependencyProperty that we know of that is bound to the property we're interested in. 
                // Now we just tell the callback and the caller will handle it.
                if (element is FrameworkElement)
                {
                    callbackDelegate((FrameworkElement)element, bb, dp);
                }
            }
        }
    }

    // Now, recurse through any child elements
    if (element is FrameworkElement || element is FrameworkContentElement)
    {
        foreach (object childElement in LogicalTreeHelper.GetChildren(element))
        {
            if (childElement is DependencyObject)
            {
                FindBindingsRecursively((DependencyObject)childElement, callbackDelegate);
            }
        }
    }
}
http://stackoverflow.com/questions/2288765/in-mvvm-with-wpf-how-do-i-unit-test-the-link-between-the-viewmodel-and-the-view

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:在使用WPF的MVVM中,如何单元测试ViewModel和View之间的链接