【发布时间】:2017-10-20 15:28:45
【问题描述】:
我尝试创建一个测试套件来测试包含某个事件的类。基本上我希望调用一个方法,给该方法一个事件,一段测试代码和一个执行事件的对象,最后是引发事件的预期次数。
我的第一次迭代是:
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));
}
}
它会被称为:
EventFireTest(obj.PropertyChanged, obj, action);
其中动作包含动作对以及一些元数据,例如正在执行的动作的视觉线索。
但是,当我尝试将事件传递给此函数时,问题是“事件只能是 += 和 -= 的 lhs。尽管那是我最终对这次活动所做的唯一事情。 (编译器理论上应该可以检查这个?)
现在为了规避这个问题,我采用了一种更臃肿的方法,直接引入了已经不需要的代码重复以及将内部细节泄露给外部测试方法。通过为要执行的EventFireTest 方法提供一个lambda。
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));
}
}
现在代码将被称为:
Action<int> setup = n => obj.PropertyChanged += (sender, e) => {
++n;
};
EventFireTest(setup, obj, action);
我认为丑陋已经很明显了(突然间我需要关心如何计算事件执行次数)。但更重要的是,上面的代码不起作用。
lambda 不会“更改”EventFireTest 中的变量,而是创建变量的本地副本,并对其进行更新。所以我需要通过引用传递整数,如果没有一些复杂的方式,这也是不可能的。
这些问题加在一起让我相信我目前没有走上解决这个问题的正确轨道。有最直接的方法吗?
【问题讨论】:
标签: c# unit-testing events lambda