断言事件扩展方法在C#中升起
问题描述:
现在我做这个断言事件扩展方法在C#中升起
bool didFire = false;
_viewModel.SomethingChanged =() => didFire = true;
_viewModel.SomeProperty = SomeValue;
Assert.IsTrue(didFire);
这有缺点:
- 的设置是丑陋的和长。
- 我需要重置每次我多次调用,例如,如果我要测试的事件在某些情况下解雇,但并非总是如此,按照一定的场景时
didFire
到false
手动。这很容易出错,因为忘记它可能会破坏测试。 - 随着许多事件/回调/情况,这导致更多的样板代码来测试简单的事件。
所以像任何像样的程序员一样,在看到自己重复完成同样的任务之后,我想将它存储在函数中。
我想出的最好主意是把它放在一个Assert
扩展方法中,但我找不到一个体面的方法,无论是我自己还是在线,都可以使它工作,并且仍然很好。
理想情况下,我在寻找的东西,将工作如下
Assert.WillBeRaised(_viewModel.SomethingChanged);
_viewmodel.SomeProperty = SomeValue;
或者,也许只是在我的问题在于周围的其他方法
_viewmodel.SomeProperty = SomeValue;
Assert.WasRaised(_viewModel.SomethingChanged);
这是,必须有人在事件发生之前收听,并且断言必须在事后完成。无论如何,无论如何,我觉得我会结束太多的代码。
有没有人得到一些干净的解决方案,这个相当普遍的问题?
答
你可能想看看Fluent Assertions。
有了这些,你可以这样做:
// this is the whole initialization
_viewModel.MonitorEvents();
// do test
_viewModel.SomeProperty = SomeValue;
// this is the whole assertion
_viewModel.ShouldRaise("SomethingChanged");
您可以扩展此检查传递给事件处理程序等方面的参数:
_viewModel.ShouldRaise("SomethingChanged")
.WithSender(_viewModel)
.WithArgs<SomethingChangedEventArgs(e => e.Name == "SomeValue");
答
你可以写这样的:
public static void WillBeRaised(Action<Action> attach, Action act)
{
bool called = false;
attach(() => called = true);
act();
Assert.IsTrue(called);
}
和用法:
WillBeRaised(
x => _viewmodel.SomethingChanged += x,
() => _viewmodel.SomeProperty = SomeValue);