我开发了测试驱动并希望测试,我实现IScrollInfo
的控件返回正确的ScrollViewer。另外,我想在ScrollOwner上测试我的控件名为InvalidateScrollInfo
。
控件如下:
private class MyControl : UserControl, IScrollInfo
{
public ScrollViewer ScrollOwner { get; set; }
... other code to implement IScrollInfo
}
我的测试(nunit)看起来像:
[Test]
public void Should_be_scrollable()
{
var ControlToTest = new MyControl();
var scrollViewer = new ScrollViewer { Content = ControlToTest };
var window = new Window { Content = scrollViewer };
window.Show();
Assert.That(ControlToTest, Is.InstanceOf<IScrollInfo>());
Assert.That(ControlToTest.ScrollOwner, Is.SameAs(scrollViewer));
}
但遗憾的是Assert.That(ControlToTest.ScrollOwner, Is.SameAs(scrollViewer));
失败了,因为ScrollOwner
是null
。
问题为什么ControlToTest.ScrollOwner
为空?
我做了什么:我查看了ScrollOwner设置的位置。这发生在HookupScrollingComponents
的{{1}}中,而ScrollContentPresenter
则调用此OnApplyTemplate
。根据我的理解,在测量元素时应用模板。这应该在显示窗口时完成。即使我添加window.Dispatcher.Invoke(new Action(() => { }), DispatcherPriority.Render);
形式:
[Test]
public void Should_be_scrollable()
{
var scrollViewer = new ScrollViewer { Content = ControlToTest };
var window = new Window { Content = scrollViewer };
window.Show();
window.Dispatcher.Invoke(new Action(() => { }), DispatcherPriority.Render);
Assert.That(ControlToTest, Is.InstanceOf<IScrollInfo>());
Assert.That(ControlToTest.ScrollOwner, Is.SameAs(scrollViewer));
}
它没有帮助。 ScrollOwner
仍然是null
。为什么呢?
加分问题:如何测试InvalidateScrollInfo()
上调用的scrollViewer
?
答案 0 :(得分:2)
必须将PHP
设置为CanContentScroll
。
比测试工作:
true
现在可以使用[Test]
public void Should_be_scrollable()
{
var ControlToTest = new MyControl();
var scrollViewer = new ScrollViewer
{
Content = ControlToTest,
CanContentScroll = true
};
var window = new Window { Content = scrollViewer };
window.Show();
Assert.That(ControlToTest, Is.InstanceOf<IScrollInfo>());
Assert.That(ControlToTest.ScrollOwner, Is.SameAs(scrollViewer));
}
进行进一步测试。
回答Bonus问题:当您将ControlToTest.ScrollOwner
更改为小于测试中的ControlToTest.ViewportHeight
时,您可以检查ControlToTest.ExtentHeight
属性以声明ControlToTest.ScrollOwner.ComputedVerticalScrollBarVisibility
} 被称为。这可能看起来像:
ScrollOwner.InvalidateScrollInfo()
与
var scrollViewer = new ScrollViewer
{
Content = ControlToTest,
CanContentScroll = true,
VerticalScrollBarVisibility = ScrollBarVisibility.Auto
};
var window = new Window { Content = scrollViewer, Height = 600 };
window.Show();
Assert.That(
ControlToTest.ScrollOwner.ComputedVerticalScrollBarVisibility,
Is.EqualTo(Visibility.Collapsed));
window.Height = 300;
Render();
Assert.That(
ControlToTest.ScrollOwner.ComputedVerticalScrollBarVisibility,
Is.EqualTo(Visibility.Visible));
答案 1 :(得分:0)
测试UI很棘手,WPF中发生的事情是,Actions被排队到Dispatcher上,只有在UI线程空闲后才会执行。所以windowWhow()之后的很多初始化都不会发生,直到你释放UI的线程来进行绑定/初始化,并将任务安排到调度程序上,执行断言的优先级非常低。在单元测试中这可能非常棘手。