Well I tried to create a test-suite to test classes which contain a certain event. Basically I wish to call a method, give that method an event, a piece of test code and an object on which the event executes, and finally the expected amount of times the event is raised.
My first iteration is:
protected void EventFireTest<T>(EventHandler theEvent, T g, TestAction<T> action) where T: class{
var invokeChangedCount = 0;
theEvent += (sender, e) => { ++invokeChangedCount; };
foreach (var actionPair in action.AllActions) {
invokeChangedCount = 0;
var num = actionPair.Item2;
var actualAction = actionPair.Item1;
actualAction(g);
Assert.That(actual: invokeChangedCount, expression: Is.EqualTo(expected: num));
}
}
It would be called like:
EventFireTest(obj.PropertyChanged, obj, action);
Where action contained the action-pair as well as some meta data like the a visual clue of the action being performed.
However when I tried to pass an event to this function, the problem was that "events can only be the lhs for += and -=". Even though that is the only thing I ultimately did with the event. (Compiler should be able to check this theoretically?)
Now to circumvent this problem I went for a more bloated approach, directly introducing already unwanted code duplication as well as bleeding internal details to the outer test method. By providing a lambda for the EventFireTest
method to execute.
protected void EventFireTest<T>(Action<int> EventSetupAction, T g, TestAction<T> action) where T: class{
var invokeChangedCount = 0;
EventSetupAction(invokeChangedCount);
foreach (var actionPair in action.AllActions) {
invokeChangedCount = 0;
var num = actionPair.Item2;
var actualAction = actionPair.Item1;
actualAction(g);
Assert.That(actual: invokeChangedCount, expression: Is.EqualTo(expected: num));
}
}
Now the code would be called as:
Action<int> setup = n => obj.PropertyChanged += (sender, e) => {
++n;
};
EventFireTest(setup, obj, action);
I think the uglyness is already quite visible (suddenly I need to care how counting the event executions is done). But more important that above code won't work.
Instead of "changing" the variable in EventFireTest
the lambda creates a local copy of the variable, and updates that. So I would need to pass the integer by reference, which is again not possible without some convoluted way.
These problems combined lead me to believe I am currently not on the right track to solve this. There most be a more straightforward way?