Right now I'm doing this
bool didFire = false;
_viewModel.SomethingChanged = () => didFire = true;
_viewModel.SomeProperty = SomeValue;
Assert.IsTrue(didFire);
This has drawbacks :
didFire
to false
manually every time I make multiple calls, for example if I want to test the event is fired in certain cases but not always, following a certain scenario. This is prone to error since forgetting it might break the test. So like any decent programmer would do, after seeing myself repeating the same task, I wanted to store it in a function.
The best idea I came up with is putting this in an Assert
extension method but I couldn't find a decent way, either myself or online, to make it work and still be nice.
Ideally, I'm looking for something that would work as follows
Assert.WillBeRaised(_viewModel.SomethingChanged);
_viewmodel.SomeProperty = SomeValue;
or, maybe just the other way around
_viewmodel.SomeProperty = SomeValue;
Assert.WasRaised(_viewModel.SomethingChanged);
And this is where my problem lies, someone must be listening before the event is raised, and the assert must be done afterwards. So either way, I feel like I'll end up too many lines of code anyway.
Has anyone got some clean solution to this rather common problem?
You may want to have a look at Fluent Assertions .
With these you can do something like:
// this is the whole initialization
_viewModel.MonitorEvents();
// do test
_viewModel.SomeProperty = SomeValue;
// this is the whole assertion
_viewModel.ShouldRaise("SomethingChanged");
You can extend this to check for the arguments passed to the event handler etc:
_viewModel.ShouldRaise("SomethingChanged")
.WithSender(_viewModel)
.WithArgs<SomethingChangedEventArgs(e => e.Name == "SomeValue");
You can write it like this:
public static void WillBeRaised(Action<Action> attach, Action act)
{
bool called = false;
attach(() => called = true);
act();
Assert.IsTrue(called);
}
And usage:
WillBeRaised(
x => _viewmodel.SomethingChanged += x,
() => _viewmodel.SomeProperty = SomeValue);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.