3

Silverlightユニットテストフレームワークで奇妙な問題が発生しています。実行される最初のメソッドは毎回失敗します。まったく同じコードで2番目のテストがあり、合格しました。初めて呼び出されたときの奇妙な点は、実際にタイムアウト待ってからリポジトリ呼び出しを実行することです(気になる場合は、その下にHTTP PUTがあります)。コードは次のとおりです。最初のコードは毎回失敗し、2番目のコードは毎回合格します。

    [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.");
        } 
    }

編集: 私の最終的な解決策は、ウラジミールの解決策の修正です:

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

3 に答える 3

12

Silverlightユニットテストフレームワークを使用している場合は、次の方法でテストを書き直してみてください。

    [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
于 2012-07-19T08:11:25.377 に答える
4

書かれたすべてを要約すると、Silverlightのユニットテストを書く際のいくつかの重要なポイントに注意する必要があります。


[Asynchronous]
テストメソッドの属性は、非同期操作を含む部分をテストしていて、テスト目的でそれらを同期したいことを示しています。Silverlightユニットテストフレームワークの非同期自体は少し歪んでいます。すべての「エンキュー」ディレクティブは、「何かが起こるまでこれを延期する」ようなものであり、従来のプログラミングの非同期の意味が持つ意味ではありません。


EnqueueConditional
言い換えれば、条件が満たされるまで待つことを意味します。そして、これは非同期テストの最も重要な部分の1つです。条件が合法になった後EnqueueCallbacks、次EnqueueConditionalが実行されるまで。

重要な注意点:

EnqueueConditionalタイマー/バックグラウンドスレッドで渡された述語を繰り返し呼び出し、毎回trueを返すかどうかを確認します。

そのため、条件内で重くて複雑なロジックを使用することは避けてください。


EnqueueCallback
EnqueueConditional条件が満たされる前にコードの実行を延期します。Actoinまたはの配列をキューに入れActionsます。


EnqueueDelay
続行する前に、最小ミリ秒/時間遅延をキューに入れます。


EnqueueTestComplete
TestComplete非同期テストを使用するときにテストが完了したこと を通知する呼び出しアクションをキューに入れます。

重要な注意(ドキュメントから):

HtmlTimerやその他のスレッドメソッドなど、独自の完了メソッドを使用する場合、 タイムアウトを使用しているときにテストがタイムアウトした後に、この呼び出しが発生する可能性があります。そのため、次のテストへの呼び出しを完了する可能性があるため、十分に注意してください。

于 2012-07-19T22:46:23.187 に答える
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();
     }
}
于 2012-07-19T08:15:15.950 に答える