2011-09-20 61 views
1

我正在嘗試編寫一個異步Silverlight單元測試,如http://developer.yahoo.com/dotnet/silverlight/2.0/unittest.html中所述。也許我正在用lambda表達式掙扎,我不確定,但我不清楚如何編寫我的命名回調,以便異步測試毫無例外地完成。目前它在TestComplete()調用中引發System.UnauthorizedAccessException(無效的跨線程訪問),我猜測它是因爲它不知道它仍然在testNullInsert()測試中?幫助在Silverlight中編寫異步單元測試

問題 - 我該如何正確編寫測試,如果我需要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的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(); 
    })); 
    })); 
    })); 
    } 
+1

無效的跨線程訪問異常是由於後臺線程試圖訪問UI線程的資源或反之。 –

+0

當然,但它發生在間接調用系統調用的異步回調「TestComplete()」的行中。 – swinefeaster

回答

1

我認爲@Anthony是正確的,這表明TestComplete()使得一些調用UI線程,並且由於它是從後臺線程調用的(因爲它是回調函數),所以會引發此異常。

從現在閱讀的文檔,它說,[Asynchronous]標籤

測試已完成TestComplete方法被調用後,才,方法不退出的時候。您的測試類必須從SilverlightTest繼承來執行異步測試

你可以嘗試把線TestComplete()testNullInsert方法結束。這可能不會拋出異常,但我認爲它不會正確執行測試。你最終想要做的是有一個測試方法,執行以下步驟,

  • 清除測試數據,並等待它完成 - 這不是測試,所以並不關心結果,但我們仍需等待使用的AutoResetEvent或繼續回調
  • 裏面定義要測試
  • 回調添加到單元測試隊列回調 - 使用EnqueueCallback()
  • 等待回調結束和存儲結果 - 使用EnqueueConditional()
  • 告知unti測試框架您已經完成 - 通過調用EnqueueTestComplete()

如果你可以重寫你的測試到的東西,看起來像this,那麼我想你會用自己的方式寫作異步單元測試您的代碼。

乾杯, Al。

1

TestComplete將發生的事情之一是UI將被更新。然而,顯然TestComplete方法(或者它最終與之交互的UI代碼)並不期望在非UI線程上被調用。

因此它似乎其由你來確保TestComplete呼叫在UI線程上執行: -

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

謝謝!我會在今天晚些時候嘗試。所以我不需要在任何地方做任何EnqueueCallback()? – swinefeaster

+0

工程就像一個魅力!唯一不可思議的是,當測試通過時,它不會出現在測試運行器中。但是,如果失敗,它確實失敗(出現錯誤,表明已經爲該測試用例設置了結果)。不理想,但它爲我所需要的技巧。謝謝! – swinefeaster

+0

不幸的是,測試並不等待測試完成,並且開始並行運行其他測試,這會導致其他問題。我認爲這與上面的兩條評論有關。另見http://stackoverflow.com/questions/4845332/tdd-unit-testing-the-viewmodel。任何想法安東尼? – swinefeaster