【问题标题】:Waiting for Event Triggering in Silverlight Unit Tests在 Silverlight 单元测试中等待事件触发
【发布时间】:2010-12-26 16:41:48
【问题描述】:

我正在使用 Silverlight 单元测试框架来测试一些视图管理器类。某些测试需要触发 PropertyChanged 事件。

我目前正在使用 EnqueueConditionalWaitHandles

的组合

示例 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();
}

这行得通。但我有一些问题困扰着我:

我真的需要使用 WaitHandle 吗?如果我只使用布尔值,它的性能是否也一样好?

示例 2

bool fHasFiredEvent = false;
manager.PropertyChanged += (sender, propChangeArgs) =>
                           { 
                               fHasFiredEvent = true;
                           }
manager.DoTheThingThatTriggersNotification();    
EnqueueConditional (() => fHasFiredEvent);
EnqueueTestComplete();

或者如果我保留 WaitHandle,但丢失了 TimeoutAttribute 并在 Wait 上超时会更好?

示例 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();
}

所以现在我写了三个例子,它们都有效。所以我的最后一个问题是

  • 哪个最好 表现? (尽管 差异可以忽略不计,它是 纯学术呀呀呀呀呀。它本身就很有趣。)
  • 这三个示例中的任何一个是否具有 根本缺陷?

【问题讨论】:

  • 我要添加一个基本缺陷,即单元测试不应该这么复杂:-)

标签: .net silverlight multithreading unit-testing


【解决方案1】:

在三个示例中没有实际运行真实代码,我不知道我可以给出权威的答案,但我的建议是使用#2,并避开#1和#3。

我浏览了 Jeff Wilcox 的 Silverlight 单元测试框架的源代码,我记得,他对 EnqueueConditional 使用了一个聪明但非常可怕的 hack,即他反复调用传递给 EnqueueConditional() 的谓词定时器/后台线程,每次检查是否返回true。 (这不是您在生产代码中想要的,但它对于测试框架来说已经足够好了,我想是逻辑。)

因此,如果您的测试需要几秒钟才能完成,我希望您的 waitHandler.WaitOne() 或者 (a) 被多次调用,从而阻塞每个线程;或 (b) 阻塞一个可能还应该做其他事情的线程。我想 (c) 也是可能的,也就是说,你可能会很幸运, WaitOne() 不会阻止任何重要的事情,只会被调用一次。但毫无疑问,#2 是使用此测试框架的“标准”方式,除非您有特定理由引入更复杂的 WaitHandle 逻辑,否则我不会尝试将测试框架推向那个方向。

也就是说,如果有人想四处寻找并提供更权威的答案,我会全神贯注:-)。

【讨论】:

  • +1 推荐“b”并解释其他可能的副作用。虽然段落不会对提高可读性造成伤害!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-17
  • 2015-02-20
  • 2016-03-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多