为什么我的 Silverlight XAML 绑定的单元测试失败? [英] Why is my unit test of my Silverlight XAML bindings is failing?

查看:46
本文介绍了为什么我的 Silverlight XAML 绑定的单元测试失败?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我定义了以下组合框:

<ComboBox x:Name="cmbCurrency" 
          ItemsSource="{Binding IsoCurrenciesList}"
          DisplayMemberPath="Description"
          SelectedValuePath="LocaleID"
          SelectedValue="{Binding CurrencyId, Mode=TwoWay">
</ComboBox>

其中 IsoCurrenciesList 是一个 IEnumerable - 由我们定义并在视图模型中声明为的类型:

Where IsoCurrenciesList is an IEnumerable<IsoCurrency> - the type being defined by us and declared in the view model as:

private IEnumerable<IsoCurrency> isoCurrenciesList;
public IEnumerable<IsoCurrency> IsoCurrenciesList
{
    get { return isoCurrenciesList; }
    set
    {
        isoCurrenciesList = value;
        RaisePropertyChangedEvent("IsoCurrenciesList");
    }
}

我的单元测试创​​建了一个视图和视图模型的实例,并在本地列表中设置了一些虚拟货币数据:

My unit test creates an instance of the view and view model and sets up some dummy currency data in a local list:

[TestInitialize]
public void TestInit()
{
    _target = new View();

    _viewModel = new ViewModel();

    var ukp = new IsoCurrency { Code = "GBP", Description = "Pound Sterling", LocaleID = 826 };
    var usd = new IsoCurrency { Code = "USD", Description = "US Dollar", LocaleID = 840 };
    var eur = new IsoCurrency { Code = "EUR", Description = "Euro", LocaleID = 978 };
    _currencies = new List<IsoCurrency> { ukp, usd, eur };

    GetUIElement<Grid>("LayoutRoot").DataContext = _viewModel;
}

private T GetUIElement<T>(string name) where T : UIElement
{
    return (T)_target.FindName(name);
}

然后调用测试方法.这应该设置货币 ComboBox.Items(通过 ItemsSource 属性)

Then the test method is called. This should set the currency ComboBox.Items (via the ItemsSource property)

[Asynchronous]
[TestMethod]
public void TestCurrencySelection()
{
    _target.Loaded += (s, e) =>
        {
            // Set the currency list explicitly
            _viewModel.IsoCurrenciesList = _currencies;

            var currencyCombo = GetUIElement<ComboBox>("cmbCurrency");
            // This assert fails as Items.Count == 0
            CollectionAssert.AreEquivalent(currencyCombo.Items, _currencies, "Failed to data-bind currencies.");

            EnqueueTestComplete();
        };

    TestPanel.Children.Add(_target);
}

我已遵循 Jeremy 上的准则Likeness 的博客,但我无法通过绑定测试.

I've followed the guidelines on Jeremy Likeness's blog but I can't get the bindings test to pass.

我尝试过测试其他属性的绑定 - 简单字符串、布尔值和整数,但在任一端所做的更改不会反映到另一端.

I've tried testing the bindings of other properties - simple strings, booleans and integers but the changes made at either end aren't reflected to the other.

我唯一能想到的是,在将视图添加到 TestPanel 以激活"绑定之后,我还需要执行另一个步骤,但我不知道它可以做什么

The only thing I can think of is that there is another step I need to do after adding the view to the TestPanel to "activate" the bindings, but I've no idea what it could be.

更新

我应该指出代码在实际应用中运行良好.根据评论(尤其是来自 Adam Sills 的评论),问题似乎出在我尚未发布的代码中 - 即它与我们构建 XAML 的方式有关,或者在我们设置 DataContext 的方式.至少我可以将精力集中在(希望)正确的领域.

I should point out that the code works fine in the actual application. Based on the comments (particularly those from Adam Sills) it looks like the problem lies in the code I haven't posted - i.e. it's something in the way we've structured the XAML or there's a difference in the way we set the DataContext. At least I can concentrate my efforts in (hopefully) the right area.

看起来控件在视图中的位置确实很重要.页面 XAML 是这样的:

It appears that the position of the control in the view does matter. The page XAML is something like this:

<Grid x:Name="LayoutRoot">
    <VisualStateManager.VisualStateGroups>
        ...
    </VisualStateManager.VisualStateGroups>

    <toolkit:BusyIndicator x:Name="activityControl" 
                           IsBusy="{Binding IsBusy}" 
                           BusyContent="{Binding BusyContent}" >
        <Grid>
            ... The page definition including sub grids, stack panels
                and the combo box I'm testing along with other controls

            <ops:SaveConfirmation Grid.Row="1" Margin="5"
                                  x:Name="saveConfirmation"
                                  SavedState="{Binding VendorSaved, Mode=TwoWay}" />
        </Grid>
    </toolkit:BusyIndicator/>
</Grid>

BusyIndi​​cator 是 Silverlight Toolkit 中的一个,SaveConfirmation 是我们编写的控件.

The BusyIndicator is the one from the Silverlight Toolkit and SaveConfirmation is a control we've written.

如果我测试 BusyIndi​​cator 上的 IsBusy 绑定是否按预期工作.但是,如果我在失败的 SaveConfirmation 上测试 SavedState 绑定 - 我在测试中将 VendorSaved 属性设置为 true 但是当我得到控制绑定值为false.

If I test the IsBusy binding on the BusyIndicator that works as expected. However, if I test the SavedState binding on the SaveConfirmation that fails - I set the VendorSaved property to true in the test but when I get the control the bound value is false.

var busyIndicator = GetUIElement<BusyIndicator>("activityControl");
Assert.AreEqual(busyIndicator.IsBusy, _viewModel.IsBusy, "Failed to data-bind busy indicator.");

var saveConfirmation = GetUIElement<SaveConfirmation>("saveConfirmation");
Assert.AreEqual(saveConfirmation.SavedState, _viewModel.VendorSaved, "Failed to data-bind saved state");

所以第一个测试通过,但第二个失败.

So the first test passes, but the second fails.

我需要做些什么来确保设置树中所有元素的绑定?

推荐答案

您已经包含了 ComboBox 的 XAML,但没有包含页面的其余部分.在您的测试中,您有 GetUIElement("LayoutRoot").DataContext = _viewModel;.在您所遵循的示例中,他定义了:

You've included the XAML for your ComboBox, but not the rest of your page. In your test you have GetUIElement<Grid>("LayoutRoot").DataContext = _viewModel;. In the example you're following, he defines:

<Grid x:Uid="LayoutRoot" x:Name="LayoutRoot" Background="White"
    DataContext="{Binding Source={StaticResource VMLocator},Path=Cascadia}">

然后他测试绑定的控件直接嵌套在该网格内.您的页面设置是否相同?

and then the controls on which he's testing the bindings are nested directly inside that grid. Is your page setup the same way?

这篇关于为什么我的 Silverlight XAML 绑定的单元测试失败?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆