سؤال

أحاول حاليًا تنفيذ ملف StopWatch صف دراسي. الواجهة شيء مثل:

interface IStopWatch {
    void Run();
    void Stop();
    int SecondsElapsed { get; }
    int MinutesElapsed { get; }
}

في الأساس ، سيحتاج تطبيقي إلى استخدام ملف StopWatch, ، ولكن لأغراض الاختبار ، سيكون من الجيد أن يكون لديك وسيلة لتعديل داعش أ StopWatchنتائج es '، وهذا هو السبب IStopWatch بدلا من .net's System.Stopwatch.

بينما أحاول تطوير هذا الاختبار الأول ، سأضطر إلى إنشاء رمز لي StopWatch الفصل فقط بعد كتابة اختباراتها. لقد أدركت بالفعل أن الاختبارات التي سأقوم بها لن تكون اختبارات الوحدة ، حيث إنني أستخدم .NET's System.Stopwatch الفصل الداخلي.

لذلك ، في تعهداتي ، الشيء الوحيد الذي يمكنني القيام به الآن هو الاختبارات التي تبدو كما يلي:

[TestMethod]
public void Right_After_Calling_Run_Elapsed_Minutes_Equals_Zero() {
    IStopWatch stopWatch = new StopWatch();
    stopWatch.Run();
    Assert.AreEqual<int>(0, stopWatch.ElapsedMinutes);
}

[TestMethod]
public void One_Second_After_Run_Elapsed_Seconds_Equals_One() {
    IStopWatch stopWatch = new StopWatch();
    stopWatch.Run();
    Thread.Sleep(1000 + 10);
    Assert.AreEqual<int>(1, stopWatch.ElapsedSeconds);
}

[TestMethod]
public void Sixty_Seconds_After_Run_Elapsed_Minutes_Equals_One() {
    IStopWatch stopWatch = new StopWatch();
    stopWatch.Run();
    Thread.Sleep(60 * 1000 + 1000);
    Assert.AreEqual<int>(1, stopWatch.ElapsedMinutes);            
}

أعلم أنه لا يمكنني تشغيل هذا الأمر بقدر ما تختلف اختبارات الوحدة الخاصة بي ، لكنني أعتقد أنه لا يوجد شيء يمكنني فعله حيال ذلك. هل مقاربي صحيح أم أفتقد شيئًا؟

شكرًا

يحرر

لذلك انتهى بي الأمر باتباع نصائح Quinn351 و Sjoerd وترميز شيء يستخدم أخصائيات البيانات بدلاً من فئة ساعة توقيت .NET:

public class MyStopWatch : IMyStopWatch {
    private DateTime? firstDateTime = null;
    private DateTime? secondDateTime = null;
    private bool isRunning = false;

    public void Start() {
        isRunning = true;
        firstDateTime = DateTime.Now;
    }

    public void Stop() {
        isRunning = false;
        secondDateTime = DateTime.Now;
    }

    public void Reset() {
        firstDateTime = null;
        secondDateTime = null;
        isRunning = false;
    }

    public TimeSpan GetTimeElapsed() {
        return secondDateTime.Value.Subtract(firstDateTime.Value);
    }
}

هذا يتيح لي إجراء تطبيقات أخرى لديها getter/setters لكلا التواريخ حتى أتمكن من جعل getTimeElapsed () إرجاع ما أريد.

هل كانت مفيدة؟

المحلول

ربما تحصل فئة ساعة التوقيت الخاصة بك على التاريخ والوقت من مكان ما. قم بعمل كائن يرجع التاريخ الحالي. سيكون هذا فئة بسيطة للغاية. عند الاختبار ، مرر في أ وهمية كائن بدلاً من ذلك ، والذي يعيد تاريخ ووقت مزيف. وبهذه الطريقة ، يمكنك التظاهر في اختبارك كما لو أن العديد من الثواني قد انقضت.

class DateTime {
    public Date getDate() {
        return System.DateTime.Now();
    }
}

class MockDateTime {
    public Date getDate() {
        return this.fakeDate;
    }
}

class StopwatchTest {
    public void GoneInSixtySeconds() {
        MockDateTime d = new MockDateTime();
        d.fakeDate = '2010-01-01 12:00:00';
        Stopwatch s = new Stopwatch();
        s.Run();
        d.fakeDate = '2010-01-01 12:01:00';
        s.Stop();
        assertEquals(60, s.ElapsedSeconds);
    }
}

نصائح أخرى

لماذا "تعديل نتائج ساعة توقيت"؟! ما هو الغرض كله من الاختبار إذا كنت ستعدل نتائجك؟

بالنسبة للاختبار ، يجب أيضًا اختبار طريقة التوقف ويجب عليك اختبار ما إذا كان مقدار الثواني أكثر من 60 مرة تقريبًا من مقدار الدقائق.

يمكن للصف الذي تكتبه أيضًا استخدام ساعة توقيت داخليًا ثم تعديل النتائج حسب الطلب (ثم يمكنك دائمًا العودة إلى النتائج الأصلية).

ملاحظة: يجب أن تكون أسماء الأسلوب أقصر وليس لها الأسس.

إحدى المشكلات هي أن ساعة التوقيت ليست دقيقة على المعالجات ذات السرعات المتغيرة على مدار الساعة ، أي معظمها الحالي ، كما يمكن رؤيته في المناقشة التالية

C# تظهر ساعة توقيت وقت غير صحيح

لذا فإن استخدام thread.sleep لن يمنحك وقتًا دقيقًا. سيكون من الأفضل تنفيذ نسختك الخاصة من ساعة الإيقاف باستخدام DateTime.زية

جانبا إلى التحرير أعلاه: لا تستخدم هذه الطريقة لتحديد الوقت المنقضي! لا يعمل بشكل جيد عندما:

  • قائمة الاغراض
  • يتم تعيين الساعة أو المنطقة الزمنية
  • يبدأ أو ينتهي التوفير في ضوء النهار
  • الساعة غير موثوقة على خلاف ذلك (على سبيل المثال داخل VM)

... وربما عدد من الشروط الأخرى.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top