- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我正在使用 Nuget (4.1.23.0) 上可用的当前版本的 MvvmLight,调用 RaiseCanExecuteChanged 似乎在单元测试中没有做任何事情。场景很简单,我有一个命令:
public RelayCommand FooCommand { get; private set; }
我在 View 模型构造函数中新建它并将它指向一些私有(private)方法:
FooCommand = new RelayCommand(Foo, CanFoo);
private void Foo()
{
// do some fooing.
}
private bool CanFoo()
{
return SomeRequiredProperty != null;
}
然后在 SomeRequiredProperty
的 setter 中我调用 RaiseCanExecuteChanged:
public object SomeRequiredProperty
{
get
{
return someRequiredProperty;
}
set
{
someRequiredProperty = value;
FooCommand.RaiseCanExecuteChanged();
}
}
现在在单元测试中,我执行以下操作:
// Arrange
var canExecuteChanged = false;
viewModel.FooCommand.CanExecuteChanged += (sender, args) => canExecuteChanged = true;
// Act
viewModel.SomeRequiredProperty = new object();
// Assert
Assert.That(canExecuteChanged, Is.True);
测试失败,因为我的事件处理程序没有触发。这是为什么?
更新:该行为确实在运行时有效。
最佳答案
已修复!
nemesv是正确的,因为 FooCommand.RaiseCanExecuteChanged()
只是调用 CommandManager.InvalidateRequerySuggested()
。
除此之外,FooCommand.CanExecuteChanged
只是将处理程序转发给 CommandManager.RequerySuggested
事件:
public event EventHandler CanExecuteChanged
{
add
{
...
CommandManager.RequerySuggested += value;
}
...
}
问题的原因是 CommandManager 中的以下代码行类:
private void RaiseRequerySuggested()
{
...
_requerySuggestedOperation = dispatcher.
BeginInvoke(
DispatcherPriority.Background,
new DispatcherOperationCallback(RaiseRequerySuggested),
null); // dispatcher is the Dispatcher for the current thread.
...
}
此行放置一个 DispatcherPriority 的工作项背景
关于 Dispatcher工作项队列。工作项应该通知 CommandManager.RequerySuggested
事件的所有处理程序。
问题 是此工作项从未运行过。
解决方案是强制调度员运行工作项。
我在 this discussion 中找到了解决方案在 MVVM 基金会 CodePlex 页面上。我设法将代码简化为以下帮助程序类。
public static class DispatcherTestHelper
{
private static DispatcherOperationCallback exitFrameCallback = ExitFrame;
/// <summary>
/// Synchronously processes all work items in the current dispatcher queue.
/// </summary>
/// <param name="minimumPriority">
/// The minimum priority.
/// All work items of equal or higher priority will be processed.
/// </param>
public static void ProcessWorkItems(DispatcherPriority minimumPriority)
{
var frame = new DispatcherFrame();
// Queue a work item.
Dispatcher.CurrentDispatcher.BeginInvoke(
minimumPriority, exitFrameCallback, frame);
// Force the work item to run.
// All queued work items of equal or higher priority will be run first.
Dispatcher.PushFrame(frame);
}
private static object ExitFrame(object state)
{
var frame = (DispatcherFrame)state;
// Stops processing of work items, causing PushFrame to return.
frame.Continue = false;
return null;
}
}
我的测试现在看起来像这样:
// Arrange
var canExecuteChanged = false;
viewModel.FooCommand.CanExecuteChanged +=
(sender, args) => canExecuteChanged = true;
// Act
viewModel.SomeRequiredProperty = new object();
DispatcherTestHelper.ProcessWorkItems(DispatcherPriority.Background);
// Assert
Assert.That(canExecuteChanged, Is.True);
而且,最重要的是,它通过了 :)
关于c# - 为什么 RelayCommand RaiseCanExecuteChanged 在单元测试中不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12033798/
今天有小伙伴给我留言问到,try{...}catch(){...}是什么意思?它用来干什么? 简单的说 他们是用来捕获异常的 下面我们通过一个例子来详细讲解下
我正在努力提高网站的可访问性,但我不知道如何在页脚中标记社交媒体链接列表。这些链接指向我在 facecook、twitter 等上的帐户。我不想用 role="navigation" 标记这些链接,因
说现在是 6 点,我有一个 Timer 并在 10 点安排了一个 TimerTask。之后,System DateTime 被其他服务(例如 ntp)调整为 9 点钟。我仍然希望我的 TimerTas
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用资料或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我就废话不多说了,大家还是直接看代码吧~ ? 1
Maven系列1 1.什么是Maven? Maven是一个项目管理工具,它包含了一个对象模型。一组标准集合,一个依赖管理系统。和用来运行定义在生命周期阶段中插件目标和逻辑。 核心功能 Mav
我是一名优秀的程序员,十分优秀!