اختبار وحدة مع NSURLConnection
-
03-07-2019 - |
سؤال
وأريد أن اختبار قطعة من التعليمات البرمجية التي تستخدم الشبكة (الطبقة NSURLConnection
، على أن تكون محددة). الرمز (دعنا نسميها NetworkManager
) يبدو قليلا مثل هذا:
- (id) buildConnection
{
// some more code and then:
return [NSURLConnection …];
}
- (void) startNetworkSync
{
id connection = [self buildConnection];
//…
}
في اختبار وحدة أود أن تخلص من الشبكات، أي. استبدال الكائن NSURLConnection
من قبل وهمية. كيف أفعل هذا؟
ولقد حاولت خلق وهمية الجزئي للNetworkManager
التي من شأنها أن تحل محل الطريقة buildConnection
من كعب. والمشكلة هي أن يسخر جزئية كما فعلت من قبل OCMock الرسائل كعب الوحيد عن العالم الخارجي - إرسال buildConnection
من startNetworkSync
استدعاء الأسلوب الأصلي، وليس كعب
ولقد حاولت أيضا الطبقة NetworkManager
من خلال فئة ترميم القرد. يعمل هذا، يمكنني بسهولة تجاوز أسلوب buildConnection
التي كتبها رمز آخر واستبدال NSURLConnection
حقيقية مع كعب. المشكلة هي أنني لا توجد طريقة بسيطة أتمكن من الحصول على اتصال فافات في الاختبار - الاتصال هو جزء خاص من NetworkManager
وبعد ذلك يمكنني أن فئة فرعية NetworkManager
، تجاوز أسلوب buildConnection
وإضافة متغير مثيل بالإضافة إلى استرجاع للاتصال تم إنشاؤها. هذا يبدو مثل الكثير من التعليمات البرمجية، وإن كان.
وكيف يمكنك حل هذا؟ أنا أبحث عن حل يحافظ على تصميم الطبقة NetworkManager
نظيفة ولا تتطلب الكثير من السحر ولا كود الكثير في الاختبار.
المحلول
وهذا هو تم تصميم هذا النوع من الشيء حقن التبعية إلى حل. إذا كنت تستخدم startNetworkSyncWithConnection:(NSURLConnection*)
بدلا يمكنك بسهولة اختبار الأسلوب مع اتصال وهمية. إذا كنت لا تريد تغيير API للعملاء الخاص بك حتى يمكن أن تبقي startNetworkSync
كما مجمع الذي لا يفعل شيئا ولكن ندعو إلى أن الطريقة الجديدة مع [self buildConnection]
كوسيطة.
نصائح أخرى
وI تعديل OCMock لدعم يسخر الحقيقي جزئية، راجع على جيثب .
وهناك حل آخر ولقد استخدمت مؤخرا هو مجردة تماما واجهة الربط الشبكي. إذا كانت الطبقة يحتاج إلى بعض البيانات من الشبكة، وربما يتفاعل مع بعض خدمة الخادم التي يمكن أن تكون على غرار explictly كبروتوكول:
@protocol SomeNetworkService
- (NSArray*) allAvailableFoos;
- (void) insertNewFoo: (Foo*) foo;
@end
وبعد ذلك سيكون لديك تنفيذ HTTP حقيقي واختبار واحد. وهذا يعني المزيد من العمل، ولكن أيضا أفضل بكثير قابلية الاختبار. الاختبارات هي أقل هشاشة وأكثر ملاءمة، لأن طبقة اختبار الشبكة يمكن أن تفعل كل ما تحتاجه.