我遇到了Silverlight Unit Test Framework的一个奇怪问题。每次执行的第一个方法都失败了。我用完全相同的代码进行了第二次测试,然后通过。第一次调用它时的奇怪之处在于它实际上等待超时然后执行存储库调用(如果你关心的话,它下面是一个HTTP PUT)。这是代码 - 第一个代码每次都失败,第二个代码每次都失败:
[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.");
}
}
修改 我的最终解决方案是对Vladmir解决方案的修改:
[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();
}
答案 0 :(得分:12)
如果您正在使用Silverlight Unit Tests Framework,请尝试下一步重写您的测试:
[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();
}
您的测试类应该派生自SilverlightTest类:
[TestClass]
public class MyTests: SilverlightTest
答案 1 :(得分:4)
总结所有已编写的内容,您应该了解编写Silverlight单元测试的几个要点。
<小时/> 的[Asynchronous]
强>
<小时/> 的
EnqueueConditional
强>
EnqueueCallbacks
,直到下一个EnqueueConditional
将被执行。
EnqueueConditional
重复调用传递给它的谓词 计时器/后台线程,每次检查它是否返回true。
这就是为什么你应该避免在条件下使用繁重,复杂的逻辑。
<小时/> 的
EnqueueCallback
强>
EnqueueConditional
满足条件。它会将Actoin
或Actions
数组排成一列。
<小时/>
EnqueueDelay
<小时/> 的
EnqueueTestComplete
强> TestComplete
的操作排入队列,这表示在使用异步测试时测试已完成。
重要说明(来自文档):
如果您使用自己的方法来完成,例如HtmlTimer或 其他线程方法,可能会发生此调用 AFTER 使用超时时测试已超时。因此,要非常小心,因为您可以完成对 next 测试的调用。
答案 2 :(得分:3)
您可以在TestMethod中使用Asynchronous关键字
[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();
}
在ViewModel中创建一个委托用于每个正在测试的方法......
public delegate void AsynCallComplete();
public event AsynCallComplete AsyncCallBackCompleted;
public void InformCallbackCompleted()
{
if (AsyncCallBackCompleted != null)
{
AsyncCallBackCompleted();
}
}