帮助在 Silverlight 中编写异步单元测试

发布于 2024-12-06 00:43:08 字数 1871 浏览 0 评论 0原文

我正在尝试编写异步 Silverlight 单元测试,如 http://developer 中所述.yahoo.com/dotnet/silverlight/2.0/unittest.html。也许我正在与 lambda 表达式作斗争,我不确定,但我不清楚如何编写我的命名回调,以便异步测试无异常地完成。目前它在调用 TestComplete() 时抛出 System.UnauthorizedAccessException (无效的跨线程访问),我猜测这是因为它不知道它仍在 testNullInsert() 测试中?

问题 - 我如何正确编写测试,如果我需要 lambda 表达式,请解释一下做什么。

以下是到目前为止我的代码:

[TestClass]
public class IdentityEditDatabaseTest : WorkItemTest
{
  [TestMethod, Asynchronous] public void testNullInsert()
  {
    wipeTestData(testNullInsertContinue1);
  }
  private void testNullInsertContinue1(String errorString)
  {
    IdentityProperties properties = new IdentityProperties(getContext());
    properties.setUserName(DATABASE_TEST);
    postUserEdit(properties, testNullInsertContinue2);
  }
  private void testNullInsertContinue2(String errorString)
  {
    Assert.assertTrue(errorString == null);

    wipeTestData(testNullInsertContinue3);
  }
  private void testNullInsertContinue3(String errorString)
  {
    TestComplete();
  }
}

谢谢!

编辑:正确的代码如下,感谢@ajmccall的 链接

[TestClass]
public class IdentityEditDatabaseTest : DatabaseTestCase
{
  [TestMethod, Asynchronous] public void testNullInsert()// throws Throwable
  {
    EnqueueCallback(() => wipeTestData(errorString1 => {

    IdentityProperties properties = new IdentityProperties(getContext());
    properties.setUserName(DATABASE_TEST);
    EnqueueCallback(() => postUserEdit(properties, errorString2 => {

    Assert.assertTrue(errorString2 == null);

    EnqueueCallback(() => wipeTestData(errorString3 => {

    EnqueueTestComplete();
  }));
  }));
  }));
  }

I am trying to write an Asynchronous Silverlight Unit Test, as mentioned in http://developer.yahoo.com/dotnet/silverlight/2.0/unittest.html. Perhaps I am struggling with lambda expressions, I am not sure, but I am unclear how to write my named callbacks so that the asynch test completes without exception. Currently it throws an System.UnauthorizedAccessException (Invalid cross-thread access) in the call the TestComplete(), which I am guessing is because it doesn't know it's still in the testNullInsert() test?

Question - how do I write the test correctly, and if I need lambda expressions, please explain what does what please.

Below is my code so far:

[TestClass]
public class IdentityEditDatabaseTest : WorkItemTest
{
  [TestMethod, Asynchronous] public void testNullInsert()
  {
    wipeTestData(testNullInsertContinue1);
  }
  private void testNullInsertContinue1(String errorString)
  {
    IdentityProperties properties = new IdentityProperties(getContext());
    properties.setUserName(DATABASE_TEST);
    postUserEdit(properties, testNullInsertContinue2);
  }
  private void testNullInsertContinue2(String errorString)
  {
    Assert.assertTrue(errorString == null);

    wipeTestData(testNullInsertContinue3);
  }
  private void testNullInsertContinue3(String errorString)
  {
    TestComplete();
  }
}

Thanks!

EDIT: Correct code is below, thanks to @ajmccall's link!

[TestClass]
public class IdentityEditDatabaseTest : DatabaseTestCase
{
  [TestMethod, Asynchronous] public void testNullInsert()// throws Throwable
  {
    EnqueueCallback(() => wipeTestData(errorString1 => {

    IdentityProperties properties = new IdentityProperties(getContext());
    properties.setUserName(DATABASE_TEST);
    EnqueueCallback(() => postUserEdit(properties, errorString2 => {

    Assert.assertTrue(errorString2 == null);

    EnqueueCallback(() => wipeTestData(errorString3 => {

    EnqueueTestComplete();
  }));
  }));
  }));
  }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

软糖 2024-12-13 00:43:08

我认为@Anthony建议 TestComplete() 对 UI 线程进行一些调用是正确的,并且由于它是从后台线程调用的(因为它是回调),因此它会导致抛出此异常。

从现在阅读文档来看,它提到了 [Asynchronous] 标签

测试仅在调用 TestComplete 方法后完成,而不是在该方法退出时完成。您的测试类必须继承自 SilverlightTest 才能执行异步测试

您可以尝试将 TestComplete() 行放在 testNullInsert 方法的末尾。这可能不会引发异常,但我认为它不会正确执行测试。您最终想要做的是拥有一种执行以下步骤的测试方法,

  • 清除测试数据并等待其完成 - 这不是测试,因此不必关心结果,但我们仍然必须使用 AutoResetEvent 等待或在回调内继续
  • 定义您要测试的回调
  • 将回调添加到单元测试队列 - 使用 EnqueueCallback()
  • 等待回调完成并存储结果 - 使用 EnqueueConditional()
  • 通知 unti 测试框架您已完成 - 通过调用 EnqueueTestComplete()

如果您可以将测试重写为某些内容看起来像这个,那么我想您将开始为代码编写异步单元测试。

干杯,
阿尔。

I think that @Anthony is right in suggesting that TestComplete() makes some call to the UI thread, and since it's called from a background thread (because it's a callback), it causes this exception to be thrown.

From reading the docs now, it says of the [Asynchronous] tag

The test has completed only after the TestComplete method is called, not when the method exits. Your test class must inherit from SilverlightTest to perform asynchronous tests

You could try putting the line TestComplete() at the end of your testNullInsert method. This may not throw the exception, but I don't think it'll be performing the test properly. What you ultimately want to do is have one test method which does the following steps,

  • Clear the test data and wait until it finishes - this is not the test, so are not concerned about the results but we still have to wait using a AutoResetEvent or continuing inside the callback
  • Define the callback that you want to test
  • Add the callback to the unit test queue - using EnqueueCallback()
  • Wait for the callback to finish and store result - using EnqueueConditional()
  • Inform the unti test framework you've finish - by calling EnqueueTestComplete()

If you can rewrite your test into something that looks like this, then I think you'll be on your way to writing asynchronous unit tests for your code.

Cheers,
Al.

我的痛♀有谁懂 2024-12-13 00:43:08

TestComplete 上将发生的事情之一是 UI 将被更新。然而,显然 TestComplete 方法(或它最终与之交互的 UI 代码)不希望在非 UI 线程上调用。

因此,您似乎需要确保对 TestComplete 的调用在 UI 线程上执行:-

  private void testNullInsertContinue3(String errorString)
  {
       Deployment.Current.Dispatcher.BeginInvoke(TestComplete); 
  }

One of the things that will happen on TestComplete is the UI will be updated. However evidently the TestComplete method (or the UI code that it eventually interacts with) is not expecting to be called on a non-UI thread.

Hence it would seem its up to you to ensure the call to TestComplete is executed on the UI thread:-

  private void testNullInsertContinue3(String errorString)
  {
       Deployment.Current.Dispatcher.BeginInvoke(TestComplete); 
  }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文