使用RelayCommands对视图模型进行单元测试

时间:2015-03-30 15:53:12

标签: c# .net nunit mvvm-light

我的视图模型单元测试存在问题。我想像这样测试我的代码:

[Test]
public void SelectCommand_ExecutedWithNull_Throws()
{
    // * Arrange
    var fixture = new Fixture();
    var sut = fixture.Build();

    // * Act & Assert
    Assert.Throws<ArgumentNullException>(() => sut.SelectCommand.Execute(null));
}

命令执行的操作:

private async void Select(IInsuranceCh insurance)
{
    if (insurance == null)
        throw new ArgumentNullException("insurance");

    try
    {
        /* ... */
    }
    catch (Exception err)
    {
        _childWindowService.ShowLoadingErrorWindow(err);
    }
    finally
    {
        IsBusy = false;
    }
}

我如何连接命令:

SelectCommand = new RelayCommand<IInsuranceCh>(Select);

但是,当我尝试这样做时,测试失败,即使抛出异常并且未在我的代码中捕获。当我试着捕捉sut.SelectCommand.Execute(null);语句时,没有输入catch块。这让我相信,RelayCommand (来自MVVM-Light Toolkit)正在吞噬异常。我该如何防止这种情况?

编辑: 一些澄清&amp; Assert.Throws

EDIT2: 已发布操作和命令连接。也许异步扮演一个角色?

1 个答案:

答案 0 :(得分:1)

原因是:RelayCommand使用反射来调用动态方法。反射会将动作的异常包装为内部异常。

When created, the TargetInvocationException is passed a reference to the exception thrown by the method invoked through reflection. The InnerException property holds the underlying exception.
https://msdn.microsoft.com/en-us/library/system.reflection.targetinvocationexception(v=vs.110).aspx

如果要从外部库中捕获异常。你必须在调试器的选项中禁用“Just My Code”。 (NUnit: Why Doesn't Assert.Throws<T> Catch My ArgumentNullException?