2

C# 3.0 と NUnit を使用しています。一定時間後に実行されるコードに対して単体テストを実行する標準的な方法があるかどうか疑問に思っています。たとえば、メソッドを登録できる単純な静的クラスがあり、n ミリ秒後に呼び出されるようにします。デリゲート メソッドのコードが呼び出されていることを確認する必要があります。

たとえば、メソッドが終了するまでアサーションが行われないため、次のテストは常にパスします。

[Test]
public void SampleTest()
{
    IntervalManager.SetTimeout(delegate{ 
        Assert.Equals(now.Millisecond + 100, DateTime.Now.Millisecond); 
    }, 100);
}

すぐには実行されないコードを単体テストすることさえ可能ですか?

乾杯、

ポール

4

7 に答える 7

2

補足として。私たちは通常、実行速度の遅いテストをNUnit カテゴリでマークしようとし、一部のビルドではそれらのテストをスキップすることを選択できます。

于 2009-05-07T06:54:07.210 に答える
2

では、正確には何をテストしているのでしょうか。タイマーが機能することをテストしていますか? または、有効期限が切れるとタイマーがコールバックを実行するように、コードでタイマーを適切に設定しますか? コードがどのようなものかわからなくても、本当にテストしたいのは後者だと思います。私の答えは、(1)これはおそらく静的メソッドでは難しいだろう、(2)おそらく依存性注入を使用して、結果のメソッドを実際に実行しないが記録するモックタイマーなどを注入する必要があるだろうということです。コードによって適切な呼び出しが行われたという期待を介して。

于 2009-03-10T03:05:23.410 に答える
2

これはどう?これにより、コールバックが起動して完了するまでに予想される最大時間の間、テストがブロックされ、エラーが報告されます。

public void Foo() {
    AutoResetEvent evt = new AutoResetEvent(false);
    Timer t = new Timer(state => {
        // Do work
        evt.Set();
    }, null, 100, Timeout.Infinite);
    if (evt.WaitOne(500)) {
        // method called and completed
    } else {
        // timed out waiting
    }
}
于 2009-03-10T03:48:45.660 に答える
1

はい、あなたの例のようにやってもうまくいきません。

むしろ、メソッドがいつ呼び出されたかを記録する、デリゲートとして使用するテスト クラスを作成することをお勧めします。

次に、テストする IntervalManager にモックを挿入します。次に、テスト メソッドは IntervalManager を待機する必要があります (IntervalManager によって提供される適切なメソッドを使用するか、数秒待機するだけです)。その後、テスト クラスの状態を確認できます。

ところで、このアプローチは通常、 モックと呼ばれます。この場合、テスト クラスはモック オブジェクトになります。

于 2009-03-10T03:02:28.517 に答える
1

他のいくつかの回答が示しているように、長時間実行されるテストは一般的に悪い考えです。このコンポーネントのテストを容易にするために、テストしようとしているものが 2 つあるということを考慮する必要があります。

  1. 時間指定デリゲートの実行を登録すると、適切な時間が設定されます。これは、タイムアウトとデリゲート数のさまざまな組み合わせでテストする必要がある可能性があります。
  2. デリゲートは適切な方法で実行されます。

このようにテストを分離すると、タイミング メカニズムが少数の短いタイムアウトで期待どおりに機能することをテストできます (考慮する必要があるすべてのケースをテストします)。システムの現在の負荷と、コンポーネント コードの複雑さ ( にある ) に基づいて、特定のデリゲートを実行するのにかかる実際の時間には、多少の余裕が必要になる可能性が高いことに注意してくださいIntervalManager

于 2009-11-06T21:45:38.260 に答える
0

Maybe I am missing something, but Visual Studio's unit testing has special attributes you can put on methods to control execution order and other things. This should have been automatically generated when you first made the unit testing project:

    #region Additional test attributes
    // 
    //You can use the following additional attributes as you write your tests:
    //
    //Use ClassInitialize to run code before running the first test in the class
    //[ClassInitialize]
    //public static void MyClassInitialize(TestContext testContext) {
    //}
    //
    //Use ClassCleanup to run code after all tests in a class have run
    //[ClassCleanup()]
    //public static void MyClassCleanup()
    //{
    //}
    //
    //Use TestInitialize to run code before running each test
    //[TestInitialize()]
    //public void MyTestInitialize()
    //{
    //}
    //
    //Use TestCleanup to run code after each test has run
    //[TestCleanup()]
    //public void MyTestCleanup()
    //{
    //}
    //
    #endregion

So using [ClassInitialize] should allow you to write whatever has to execute first into a method. Then your tests can run. Or you can use [TestInitialize] to run code before each test.

于 2009-11-06T21:33:05.743 に答える
0

もちろん、テストできます。実行されるのを待つだけです。

于 2009-03-10T02:51:32.460 に答える