سؤال

أنا أكتب اختبارًا لجزء من التعليمات البرمجية يحتوي على IOException الذي أحاول تغطيته.تبدو تجربة المحاولة/الالتقاط كما يلي:

try {
    oos = new ObjectOutputStream(new FileOutputStream(cacheFileName));
} catch (IOException e) {
    LOGGER.error("Bad news!", e);
} finally {

يبدو أن الطريقة الأسهل هي جعل FileOutputStream يرمي FileNotFoundException، ولكن ربما أكون مخطئًا في هذا الأمر.

أي شخص هناك لديه أي نصائح؟

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

المحلول

ومن تعليقك:

<اقتباس فقرة>   

نعم، أعتقد يجب على السؤال   كانت حقا "كيف يمكنني إنشاء   الملفات التي لا وجود لها على حد سواء لينكس   ويندوز؟ "في ويندوز، ويمكن استخدام   "الجديد ملف (" X: / ") '، حيث X: هو محرك   الرسالة التي لا وجود لها. على لينكس،   هذا لا يعمل لأن هذا هو   اسم ملف صالح.

وانظروا java.io.File.createTempFile. استخدامه لإنشاء ملف ثم قم بحذفه.

وربما تمر عليه شيئا مثل:

File tempFile;

tempFile = createTempFile(getClass().getName(), 
                          Long.toString(System.currentTimeMillis());
tempFile.delete();

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

نصائح أخرى

هل يمكن وضع cacheFileName إلى اسم غير صالح أو إلى أحد تعلمون لا وجود لها.

هناك جزأين لأي اختبار:تحقيق ذلك وقياس أنك حصلت على النتيجة الصحيحة.

حقن الخلل

الإجابة الأسهل هي تلك التي سبق ذكرها، وهي الضبط cacheFileName إلى ملف لن يكون موجودًا أبدًا.من المحتمل أن تكون هذه هي الإجابة الأكثر عملية في هذه الحالة.

ومع ذلك، للتسبب في حالة تعسفية مثل IOException, ، ما تريده حقًا هو حقن الخلل.يؤدي هذا إلى حدوث أخطاء في التعليمات البرمجية الخاصة بك دون إجبارك على استخدام التعليمات البرمجية المصدر الخاصة بك.فيما يلي بعض الطرق للقيام بذلك:

  • كائنات وهمية يمكنك استخدام طريقة المصنع لإنشاء تجاوز ObjectOutputStream أو FileOutputStream.في رمز الاختبار، سيرمي التنفيذ ملف IOException عندما تريد ذلك، وفي كود الإنتاج لن يعدل السلوك الطبيعي.
  • حقن التبعية من أجل وضع الكائن الوهمي الخاص بك في المكان المناسب، يمكنك استخدام إطار عمل مثل ربيع أو التماس "لحقن" الكائن المناسب في الفصل الذي يقوم بهذا العمل.يمكنك أن ترى أن هذه الأطر لها أولوية أيضًا للكائنات التي سيتم حقنها، بحيث يمكنك أثناء اختبار الوحدة تجاوز كائنات الإنتاج بكائنات الاختبار.
  • الجانب برمجة بدلاً من تغيير بنية التعليمات البرمجية الخاصة بك على الإطلاق، يمكنك استخدام AOP لإدخال الخطأ في المكان الصحيح.على سبيل المثال، باستخدام الجانب J يمكنك تحديد أ بوينكت حيث أردت أن يتم طرح الاستثناء منه، والحصول على نصيحة رمي الاستثناء المطلوب.

هناك إجابات أخرى لحقن الخطأ في Java؛على سبيل المثال منتج يسمى مسبار لقد كانت شركة رائدة في ما يمكن تسميته بـ AOP في لغة C منذ فترة طويلة، ولديها أيضًا منتج Java.

تصديق

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

وأفترض أن المسجل هو log4j;لحل مشكلة مماثلة، قمت بتطبيق مُلحق log4j الخاص بي والذي يلتقط مخرجات log4j:أنا التقاط على وجه التحديد فقط ERROR و FATAL, ، والتي من المحتمل أن تكون رسائل السجل المثيرة للاهتمام في مثل هذه الحالة.تمت الإشارة إلى الملحق في log4j.xml ويتم تنشيطه أثناء التشغيل التجريبي لالتقاط مخرجات سجل الأخطاء.هذا في الأساس كائن وهمي، لكن لم أضطر إلى إعادة هيكلة كل التعليمات البرمجية الخاصة بي التي حصلت على log4j Logger.

<اقتباس فقرة>   

وأنا أكتب اختبار للحصول على قطعة من التعليمات البرمجية   يحتوي على الصيد IOException في ذلك   أن أحاول تغطية.

وأنا لست متأكدا تماما وأنا أفهم هدفك، ولكن إذا كنت ترغب في اختبار إذا تم طرح استثناء، يمكن أن أقول لكم اختبار تتوقع أن رمي استثناء:

@Test(expected=IOException.class)
سوف

واختبار لديك ثم تفشل إذا لم يتم طرح الاستثناء، وتنجح إذا تم رميها (مثل حالة عدم وجود ملف cacheFileName).

وA FileNotFoundException أن يؤدي الواضح أن الصيد. يذكر جافادوك الحالات حيث سيتم طرح ذلك.

ويجب عليك أن تنظر أيضا أن منشئ ObjectOutputStream يمكن رمي IOException ذلك قد ترغب في تغطية هذه الحالة في الاختبارات الخاصة بك.

واثنين من الطرق السهلة ستكون إما تعيين cacheFileName إلى ملف غير موجود أو تعيين الملف المحدد للقراءة فقط الوصول.

و-جون

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

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

cacheFileName = "thisFileShouldNeverExistAndIfItDoesYouAreScrewingUpMyTests";

هل أنت متأكد أنك قادر على اتخاذ خطوات والقفز من خلال الأطواق لجعل برمجيا من أن اسم الملف سوف أبدا، من أي وقت مضى، وجود على الإطلاق، أو يمكنك استخدام سلسلة من شأنها أن توجد أبدا في 99.99999٪ من الحالات.

وآمل أن يكون هذا هو ما يعنيه.

if(new File(cachedFile).exists()) {
    oos = new ObjectOutputStream(new FileOutputStream(cacheFileName));
    //do your code here
} else {
    throw new FileNotFoundException("File doesn't exist!");
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top