Reputation: 919
I'm having a weird issue with Silverlight Unit Test Framework. The very first method executed fails, every time. I have a second test with the exact same code, and it passes. The strange thing about the first time it's called is that it actually waits for the timeout and then executes the repository call (underneath it's an HTTP PUT if you care). Here's the code - the first one fails every time, second one passes every time:
[TestMethod]
public void AuthShouldSucceed()
{
var autoResetEvent = new AutoResetEvent(false);
_authRepository.Authenticate(_username, _password, response =>
{
Assert.IsTrue(response);
autoResetEvent.Set();
});
if (!autoResetEvent.WaitOne(Constants.Timeout))
{
Assert.Fail("Test timed out.");
}
}
[TestMethod]
public void AuthShouldSucceed2()
{
var autoResetEvent = new AutoResetEvent(false);
_authRepository.Authenticate(_username, _password, response =>
{
Assert.IsTrue(response);
autoResetEvent.Set();
});
if (!autoResetEvent.WaitOne(Constants.Timeout))
{
Assert.Fail("Test timed out.");
}
}
Edit: My final solution is a modification of Vladmir's solution:
[TestMethod]
[Asynchronous]
public void AuthShouldSucceed()
{
var complete = false;
var result = false;
_authRepository.Authenticate(_username, _password, response =>
{
complete = true;
result = response;
});
EnqueueConditional(() => complete);
EnqueueCallback(() => Assert.IsTrue(result));
EnqueueTestComplete();
}
Upvotes: 3
Views: 1130
Reputation: 6260
Summarizing all written you should be aware of couple important points in writing Unit Tests for Silverlight.
[Asynchronous]
EnqueueConditional
EnqueueCallbacks
until the next EnqueueConditional
will be executed.
EnqueueConditional
repeatedly calls the predicate passed to it on a timer/background thread, checking each time to see if it returns true.
That's why you should avoid using heavy, complex logic within conditions.
EnqueueCallback
EnqueueConditional
that precedes it will met condition. It enqueues an Actoin
or an array of Actions
.
EnqueueDelay
EnqueueTestComplete
TestComplete
which signals that a test is complete when using Async testing.
Important Note(from documentation):
If you use your own methods for completing, such as an HtmlTimer or other threading method, it is possible that this call will occur AFTER the test has timed out when using Timeouts. As such, be very careful as you could complete the call to the next test.
Upvotes: 4
Reputation: 3839
If you're using Silverlight Unit Tests Framework try to rewrite your test next way:
[TestMethod]
[Asynchronous]
public void AuthShouldSucceed()
{
var done = false;
var authResult = false;
_authRepository.Authenticate(_username, _password, response =>
{
var done = true;
authResult = response;
});
EnqueueConditional(() => done);
EnqueueCallback(() => Assert.IsTrue(authResult));
EnqueueTestComplete();
}
Your test class should be derived from SilverlightTest class:
[TestClass]
public class MyTests: SilverlightTest
Upvotes: 12
Reputation: 131
You can use the Asynchronous keyword in the TestMethod
[TestMethod]
[Asynchronous]
[Description("This test checks when NULL is passed")]
public void Testing()
{
bool done = false;
EnvViewModel test = new EnvViewModel ();
.
.
test.AsyncCallBackCompleted += (() => done = true);
EnqueueCallback(() => test.DataCommand.Execute(null));
EnqueueConditional(() => done);
EnqueueCallback(() => Assert.IsTrue(test.AADTDecisionModelList.Count == 0,
"The result does not have any data."));
EnqueueTestComplete();
}
And make a delegate in the ViewModel to be used to every method that is being tested...
public delegate void AsynCallComplete();
public event AsynCallComplete AsyncCallBackCompleted;
public void InformCallbackCompleted()
{
if (AsyncCallBackCompleted != null)
{
AsyncCallBackCompleted();
}
}
Upvotes: 3