开发者

Waiting for Event Triggering in Silverlight Unit Tests

I am using the Silverlight Unit Testing Framework to test some View Manager classes. Some tests require the PropertyChanged events to be fired.

I'm currently using a combination of EnqueueConditional and WaitHandles

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

This works. But I've got questions nagging at me:

Do I actually need to use a WaitHandle? Would it perform equally as well if I just used a bool?

Example 2

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

Or would it be better if I开发者_StackOverflow kept the WaitHandle, but lost the TimeoutAttribute and timed out on the Wait?

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

So now I've written three examples, and they all work. So my final question is

  • Which would have the best performance? (Even though the difference is negligible and it's purely academic yada yada yada. It's interesting for its own sake.)
  • Do any of the three examples have fundamental flaws?


Without actually running real code in the three examples, I don't know that I can give an authoritative answer, but my advice would be to use #2, and steer well clear of #1 and #3.

I've poked through the source for Jeff Wilcox' Silverlight Unit Test Framework, and as I recall, he uses a clever but really horrible hack for the EnqueueConditional, i.e., he repeatedly calls the predicate passed to EnqueueConditional() on a timer/background thread, checking each time to see if it returns true. (It's not what you want in production code, but it's good enough for a test framework is the logic, I suppose.)

So if your test takes a couple seconds to complete, I would expect your waitHandler.WaitOne() either (a) to be called numerous times, blocking each thread as it goes; or (b) to block a thread that may be supposed to be doing other things as well. I suppose a (c) is also possible, i.e., you might get lucky, the WaitOne() wouldn't block anything important, and would only get called once. But certainly #2 is the "standard" way of using this test framework, and unless you had a specific reason to introduce the more complex logic of a WaitHandle, I wouldn't try to push the test framework in that direction.

That said, if anybody wants to poke around and deliver a more authoritative answer, I'm all ears :-).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜