And*_*erd 4 .net silverlight multithreading unit-testing
我正在使用Silverlight单元测试框架来测试一些View Manager类.某些测试需要触发PropertyChanged事件.
我目前正在使用EnqueueConditional和WaitHandles的组合
例1
[TestMethod]
[Asynchronous]
[Timeout(1000)]
public void TestNotificationExample()
{
var manager = new UserManager();
var waitHandle = new ManualResetEvent(false);
manager.PropertyChanged += (sender, propChangArgs) =>
{
waitHandler.Set();
};
manager.DoTheThingThatTriggersNotification();
// The notification event fires aynshronously to this
EnqueueConditional (() => waitHandler.WaitOne(0));
// Enqueue other tests here....
EnqueueTestComplete();
}
Run Code Online (Sandbox Code Playgroud)
这有效.但我有些问题唠叨着我:
我真的需要使用WaitHandle吗?如果我只使用一个bool,它会表现得同样如此吗?
例2
bool fHasFiredEvent = false;
manager.PropertyChanged += (sender, propChangeArgs) =>
{
fHasFiredEvent = true;
}
manager.DoTheThingThatTriggersNotification();
EnqueueConditional (() => fHasFiredEvent);
EnqueueTestComplete();
Run Code Online (Sandbox Code Playgroud)
或者如果我保留WaitHandle会更好,但会丢失TimeoutAttribute并在等待时间超时?
例3
[TestMethod]
[Asynchronous]
public void TestNotificationExample()
{
var manager = new UserManager();
var waitHandle = new ManualResetEvent(false);
manager.PropertyChanged += (sender, propChangArgs) =>
{
waitHandler.Set();
};
manager.DoTheThingThatTriggersNotification();
EnqueueCallback (() => Assert.IsTrue(waitHandler.WaitOne(1000));
EnqueueTestComplete();
}
Run Code Online (Sandbox Code Playgroud)
所以现在我写了三个例子,它们都有效.所以我的最后一个问题是
如果没有在三个示例中实际运行实际代码,我不知道我可以给出权威的答案,但我的建议是使用#2,并且很好地避开#1和#3.
我已经浏览了Jeff Wilcox的Silverlight单元测试框架的源代码,我记得,他为EnqueueConditional使用了一个聪明但非常可怕的黑客,即他反复调用在计时器/背景上传递给EnqueueConditional()的谓词线程,每次检查它是否返回true.(这不是你想要的生产代码,但我认为测试框架就足够了.)
因此,如果您的测试需要几秒钟才能完成,我希望您的waitHandler.WaitOne()要么多次调用(a),要么阻塞每个线程; 或(b)阻止可能应该做其他事情的线程.我想(c)也是可能的,也就是说,你可能会幸运,WaitOne()不会阻止任何重要的东西,并且只会被调用一次.但肯定#2是使用这个测试框架的"标准"方式,除非你有一个特定的理由来介绍WaitHandle的更复杂的逻辑,否则我不会试图将测试框架推向那个方向.
也就是说,如果有人想要四处寻找并提供更具权威性的答案,我全都耳朵:-).
| 归档时间: |
|
| 查看次数: |
1383 次 |
| 最近记录: |