سؤال

وأريد أن التعامل مع استثناء ManagementException لرمز الخطأ محددة فقط وأواجه صعوبة في كتابة اختبار وحدة لذلك. عادة، أود أن أكتب الاختبار بحيث يكون شيء كما يلي:

Searcher search = MockRepository.GenerateMock<Searcher>(); 
// wrapper for ManagementObjectSearcher

...

search.Expect(s => s.Get()).Throw(new ManagementException());

...

ولكن، هذا لا تعيين رمز الخطأ لتلك التي أريد على وجه الخصوص، في الواقع ManagementException لايوجد منشئ التي تحدد هذه القيمة.

وكيف يمكن القيام بذلك؟

و(لاحظ أن أستخدمه RhinoMocks كإطار ساخرا بلدي ولكن أنا على افتراض أن هذا هو إطار مستقل، كل ما تحتاج إلى معرفته هنا هو كيفية إنشاء ManagementException التي لديها قيمة رمز الخطأ محددة أيضا لقد وجدت بعض الإشارات إلى. طريقة System.Management.ManagementException.ThrowWithExtendedInfo(ManagementStatus errorCode) على الانترنت ولكن هذا لا يبدو أن للجمهور).

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

المحلول

ووأقل جهد للحصول على هذه العقبة سيكون المساعد ثابت أسلوب / أداة تستخدم انعكاس الإختراق فتحة في رمز الخطأ المطلوب. باستخدام العاكس اكثر من ممتاز، وأرى أن هناك حقل خاص "رمز الخطأ"، وهو يحدد فقط عبر ctors داخلية محددة في ManagementException. لذلك:)

public static class EncapsulationBreaker
   {
      public static ManagementException GetManagementExceptionWithSpecificErrorCode(ManagementStatus statusToBeStuffed)
      {
         var exception = new ManagementException();
         var fieldInfo = exception.GetType().GetField("errorCode", 
            BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField | BindingFlags.DeclaredOnly);
         fieldInfo.SetValue(exception, statusToBeStuffed);
         return exception;
      }
   }

والتحقق من أنه يعمل

[Test]
      public void TestGetExceptionWithSpecifiedErrorCode()
      {
         var e = EncapsulationBreaker.GetManagementExceptionWithSpecificErrorCode(ManagementStatus.BufferTooSmall);
         Assert.AreEqual(ManagementStatus.BufferTooSmall, e.ErrorCode);
      }

وعلى الرغم من أن على I عبوس عموما على التفكير في الاختبارات ، أو هذا هو واحد من الحالات النادرة حيث أنه مطلوب / مفيدة.
HTH

نصائح أخرى

واشتقاق فئة من ManagementException وإخفاء تنفيذ رمز الخطأ مع بنفسك. هل لديك عودة وهمية لديك هذه الفئة.

هل لديك طريقة بسيطة جدا والصغيرة أو الطبقة التي يمسك هذا الاستثناء ويحصل على رمز الخطأ للخروج منه، ثم يمر ذلك إلى الدرجة الحقيقية التي لا عمل. تحت الاختبار، استبدل هذا الرمز مع مرور مباشرة إلى الدرجة الحقيقية ما كنت تمر عند الحصول على هذا رمز الخطأ.

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

وأود أن فئة فرعية ManagementException وفي فئة فرعية تجاوز جالبة ErrorCode (إذا كانت مستويات حماية طبيعية يمنعك من فعل ذلك، ربما التأمل يمكن أن تحصل أقرب). أي رمز الذي يعالج ManagementException لكن لم يسمع قط عن فئة فرعية محددة يجب التعامل مع فئة فرعية بك "كما لو" كان ManagementException التي تحاول محاكاة لأغراض الاختبار، بعد كل شيء.

تعديل : في انها يعقل أن ErrorCode فقط لا يمكن أن يتم تجاوز (أنا أكره اللغات التي هي جامدة حتى يتمكنوا من وقف التجارب في هذا الطريق، ولكن لا يمكن إنكار وجودها ؛-). في هذه الحالة، <م> التبعية حقن لا يزال يوفر لك - DI هي واحدة من المفضلة أنماط لاختبار

.

والغرض DI في الاختبار لفصل رمز تحت الاختبار من الافتراضات الصارمة التي من شأنها أن تحول دون قابلية الاختبار - وهذا فقط ما لدينا هنا، ولو في شكل غير عادي. التعليمات البرمجية تحت الاختبار حاليا لا، ويقول، x.ErrorCode للحصول على رمز الخطأ الاستثناء س. جيد جدا، ويجب أن تفعل بعد ذلك، بدلا من ذلك، getErrorCode(x) حيث getErrorCode هو مندوب التي لا عادة فقط return x.ErrorCode. ويجب أن يكون واضعة لمندوب getErrorCode، بحيث لأغراض الاختبار، يمكنك تغييره إلى مندوب التي لا return 23 (أو أي قيمة رمز الخطأ الذي تريد محاكاة للاختبار).

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

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