c# - 在私有(private)委托(delegate)方法中测试异常

标签 c# wpf unit-testing exception mvvm

我正在以 MVVM 方式设计一个 WPF 应用程序,我有一个问题,当消息由另一个 View 模型发送时,如何测试是否引发了该异常。我正在使用 nUnit 进行单元测试。

当通过 messenger 发送的对象为空时,我尝试测试委托(delegate)抛出异常。

请在下面找到简单的代码
CTOR (所有依赖项都使用 Autofac 注入(inject))

    public ManagerViewModel (IMessenger messenger)
    {
       messenger.Register<Person> (this, OnPersonSent)
    }

代表

    private void OnPersonSent()
    {
       if(Person is null) throw new ArgumentNullException();
    }

单元测试
当我尝试如下断言时,它不会捕获异常。情况是,当信使发送消息时,OnPersonSent 方法应该抛出异常 - 但是如果此断言仅捕获 lambda 表达式中传递的方法抛出的异常,如何使用 Assert.Throws 捕获它(如果我错了,请纠正我) .下面的测试用例:

    [SetUp]
    public void SetUp()
    {
      messenger = new Messenger() // MVVMLight messenger
      sut = new ManagerViewModel(messenger)
    }

下面在 lambda 表达式中,我发送空对象,以便由上面指出的委托(delegate)抛出异常

    [Test] 
    public void OnPersonSent_WhenNull_ThrowsException()
    {    
           Assert.Throws<ArgumentNullException>(()=>messenger.Send((Person)null));
    }

非常感谢您的帮助。

PS。当然,为了清楚地显示问题,这个案例被简化了

最佳答案

查看以下最小示例,了解如何测试委托(delegate)的调用是否符合预期行为

注意:(使用 MOQ 模拟框架来模拟依赖项。)

[TestClass]
public class MyTestClass {
    [TestMethod]
    public void OnPersonSent_WhenNull_ThrowsException() {
        //Arrange
        var mock = new Mock<IMessenger>();
        Action<Person> callback = null;
        //setup the mock so the delegate can be captured when registered
        mock
            .Setup(_ => _.Register(It.IsAny<object>(), It.IsAny<Action<Person>>(), It.IsAny<bool>()))
            .Callback((object obj, Action<Person> action, bool _) => {
                callback = action; //<--
            });

        //Act
        //create view model to invoke register and capture callback in mock
        var sut = new ManagerViewModel(mock.Object);

        //Assert
        Assert.IsNotNull(callback);
        Assert.ThrowsException<ArgumentNullException>(() => callback(null));
    }
}

public class ManagerViewModel {
    public ManagerViewModel(IMessenger messenger) {
        messenger.Register<Person>(this, OnPersonSent);
    }

    private void OnPersonSent(Person person) {
        if (person is null) throw new ArgumentNullException();
    }
}

internal class Person {
}

创建并设置了一个 Messenger 的模拟以期待适当的 Register要调用的成员。设置模拟以捕获主题类的构造函数中提供的委托(delegate)方法。

一旦委托(delegate)被捕获,就可以调用它并断言预期的行为。

在测试中调用委托(delegate)与实际信使在 Send 时调用注册委托(delegate)时相同。被调用。

上面显示的方法隔离了单元测试中的调用。

请注意,上面的测试使用默认的 MSTest,但它可以很容易地应用于其他测试框架。

关于c# - 在私有(private)委托(delegate)方法中测试异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60590317/

相关文章:

c# - ListView分组和选择

c# - MVVM 界面框架

c# - Azure 存储将 blob 移动到其他容器

c# - 如何使用 MVVM 将焦点设置到文本框?

wpf - 如何更改 Datagrid 滚动条的大小?

java - 如何为 native Selenium 方法编写单元测试用例

python - Doctest python 中的私有(private)方法

unit-testing - DUnitX 从字符串到整数数组的转换

c# - COM 返回不实现任何接口(interface)的类型

c# - 在 VS Designer 中公开类型列表 <class> 的属性限制/隐藏对成员的访问或将属性显示为可扩展菜单?