我正在以MVVM方式设计WPF应用程序,但遇到一个问题,即如何测试当另一个视图模型发送消息时引发了异常。我正在使用nUnit进行单元测试。
我尝试测试当通过Messenger发送的对象为null时,委托是否引发异常。
请在下面找到简单的代码
CTOR (所有依赖项都使用Autofac注入)
public ManagerViewModel (IMessenger messenger)
{
messenger.Register<Person> (this, OnPersonSent)
}
代理
private void OnPersonSent()
{
if(Person is null) throw new ArgumentNullException();
}
单元测试
当我尝试如下声明时,它不会捕获异常。情况是,当Messenger发送消息时,OnPersonSent方法应该引发异常-但是如何使用Assert捕获它。如果此断言仅捕获由lambda表达式传递的方法引发的异常,则抛出该异常(如果我错了,请更正我) 。下面的测试用例:
[SetUp]
public void SetUp()
{
messenger = new Messenger() // MVVMLight messenger
sut = new ManagerViewModel(messenger)
}
下面在lambda表达式中,我正在发送空对象,以抛出上面所指向的委托引发的异常
[Test]
public void OnPersonSent_WhenNull_ThrowsException()
{
Assert.Throws<ArgumentNullException>(()=>messenger.Send((Person)null));
}
非常感谢您的帮助。
PS。当然,此案例经过简化以清楚地表明问题所在
答案 0 :(得分:1)
查看以下最小示例,以了解如何测试预期行为的委托调用
注意:(使用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
成员。该模拟程序的设置是为了捕获主题类的构造函数中提供的委托方法。
捕获到委托后,就可以调用它并声明预期的行为。
在测试中调用委托与调用Send
时实际的Messenger调用注册的委托时相同。
上面显示的方法在单元测试中隔离了调用。
请注意,上述测试使用默认的MSTest,但可以轻松应用于其他测试框架。