بحث باسم الموضوع المطلوب

تم طرح استثناء NetworkImageLoadException التالي لحل مشكلة ترميز الصورة



عند اختبار عناصر واجهة المستخدم التي تحتوي على عنصر واجهة المستخدم Image.network، قد تواجه خطأ NetworkImageLoadException. يحدث هذا لأن Image.network تحاول إجراء طلبات HTTP فعلية أثناء الاختبارات، وهو أمر غير مسموح به في بيئة اختبار Flutter. لمعالجة هذه المشكلة، يقوم Flutter تلقائيًا بإرجاع استجابات فارغة برمز حالة 400 (طلب سيئ) عند إجراء طلبات HTTP فعلية أثناء الاختبار. في هذا المنشور، ستتعلم ثلاثة حلول لاختبار عناصر واجهة المستخدم التي تحتوي على عنصر واجهة المستخدم Image.network بنجاح في Flutter.

تطبيق توضيحي بسيط

خلال هذه التدوينة، سوف نقوم باختبار HomePageالأداة، كما هو موضح في الملف أدناه main.dart:


 import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: HomePage(),
    );
  }
}

class HomePage extends StatelessWidget {
  const HomePage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Image.network('https://picsum.photos/id/182/350/250'),
      ),
    );
  }
}

تعرض الأداة HomePageببساطة صورة الشبكة باستخدام Image.networkالأداة. Image.networkتقوم الأداة بجلب صورة من picsum.photos .




حالة اختبار فاشلة تؤدي إلى رمي NetworkImageLoadException
بعد إنشاء تطبيق العرض التوضيحي الخاص بنا، يمكننا كتابة اختبار الأداة التالي لاختبار أداتنا  HomePage:

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:network_image_load_exception/main.dart';

void main() {
  testWidgets('Network Image Test', (WidgetTester tester) async {
    await tester.pumpWidget(const MaterialApp(home: HomePage()));

    Finder image = find.byType(Image);
    Image imageWidget = tester.widget(image);
    final networkImageWidget = imageWidget.image as NetworkImage;

    expect(image, findsOneWidget);
    expect(imageWidget.image, isA<NetworkImage>());
    expect(networkImageWidget.url, 'https://picsum.photos/id/182/350/250');
  });
}


تعرض الأداة HomePageببساطة صورة الشبكة باستخدام Image.networkالأداة. Image.networkتقوم الأداة بجلب صورة من picsum.photos .
في مقتطف التعليمات البرمجية هذا، نقوم بإنشاء اختبار عنصر واجهة مستخدم HomePageللعنصر. نبدأ حالة الاختبار بضخ العنصر HomePageالمغلف في MaterialAppعنصر واجهة مستخدم. بعد ذلك، نقوم بتحديد Imageموقع العنصر باستخدام find.byTypeالدالة.

لسبب ما، لن تتمكن من العثور على Image.networkالأداة عن طريق استخدام النوع مباشرة NetworkImageفي find.byTypeالوظيفة.

بعد العثور على الأداة، نستخدم الدالة tester.widgetللوصول إلى خصائصها. في السطر التالي، نقوم بتحويل الأداة من النوع Imageإلى NetworkImage.

ومع ذلك، عندما نجري هذا الاختبار، فإنه سيفشل. وكما ذكرنا في المقدمة، فإنه سيحاول إجراء مكالمة شبكة حقيقية، وهو ما لا تسمح به إرشادات Flutter.



حل NetworkImageLoadException
لإصلاح حالات الاختبار الفاشلة، سنستعرض ثلاثة حلول ممكنة.

1. إصلاح سهل دون استخدام أي حزمة
لحل الخطأ دون الاعتماد على أي حزمة خارجية، يمكنك تعطيل تجاوزات HTTP المخصصة والسماح للأداة Image.networkباستخدام سلوك الشبكات الافتراضي في Flutter. إليك كود الاختبار المحدث:


import 'dart:io';

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:network_image_load_exception/main.dart';

void main() {
  setUpAll(() => HttpOverrides.global = null);

  testWidgets('Network Image Test', (WidgetTester tester) async {
    await tester.pumpWidget(const MaterialApp(home: HomePage()));
    await tester.pumpAndSettle();

    Finder image = find.byType(Image);
    Image imageWidget = tester.widget(image);
    NetworkImage networkImageWidget = imageWidget.image as NetworkImage;

    expect(image, findsOneWidget);
    expect(imageWidget.image, isA<NetworkImage>());
    expect(networkImageWidget.url, 'https://picsum.photos/id/182/350/250');
  });
}

في هذا الإصدار المحدث، نقوم بالاستيراد  dart:io للوصول إلى  global خاصية الفصل HttpOverrides. بعد ذلك، في setUpAllالدالة، نتجاوز قيمة الخاصية globalإلى null. وهذا يضمن استخدام سلوك الشبكة الافتراضي أثناء اختبارات الأداة. كما أضفنا الدالة tester.pumpAndSettleللتأكد من انتهاء بناء الأداة.

نتيجة لذلك، لم يعد Flutter يعيد استجابات فارغة برمز حالة  400  (طلب سيء) عند إجراء طلبات HTTP فعلية.


2. استخدم حزمة Mocktail Image Network
هناك طريقة أخرى تتمثل في استخدام  حزمة Mocktail Image Network  ، والتي توفر طريقة ملائمة لمحاكاة صور الشبكة أثناء اختبار الأدوات. وفيما يلي الخطوات اللازمة لاستخدام هذه الحزمة: https://pub.dev/packages/mocktail_image_network

الخطوة 1: إضافة الحزمة إلى تبعيات التطوير الخاصة بك
قم بتنفيذ الأمر التالي لإضافة حزمة Mocktail Image Network إلى مشروعك: 


flutter pub add mocktail_image_network --dev



تأكد من  dev_dependencies تضمين  pubspec.yaml حزمة Mocktail Image Network الخاصة بك:
dev_dependencies:
  mocktail_image_network: ^1.2.0

الخطوة 2: تحديث اختبار الأداة
الآن بعد أن قمنا بتثبيت الحزمة، يمكننا تغيير اختبار الأداة الخاص بنا ليبدو بهذا الشكل:

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mocktail_image_network/mocktail_image_network.dart';
import 'package:network_image_load_exception/main.dart';

void main() {
  testWidgets('Network Image Test', (WidgetTester tester) async {
    await mockNetworkImages(() async => await tester.pumpWidget(
          const MaterialApp(home: HomePage()),
        ));

    Finder image = find.byType(Image);
    Image imageWidget = tester.widget(image);
    NetworkImage networkImageWidget = imageWidget.image as NetworkImage;

    expect(image, findsOneWidget);
    expect(imageWidget.image, isA<NetworkImage>());
    expect(networkImageWidget.url, 'https://picsum.photos/id/182/350/250');
  });
}



في مقتطف التعليمات البرمجية هذا، نبدأ باستيراد حزمة Mocktail Image Network. والتي توفر الوظيفة mockNetworkImages. بعد ذلك، نقوم بتغليف عملية إنشاء الأداة بالوظيفة  mockNetworkImages . وهذا يضمن  Image.network اعتراض مكالمات الشبكة التي تقوم بها الأداة واستبدالها باستجابات وهمية أثناء الاختبار.





3. استخدم حزمة Network Image Mock
بدلاً من ذلك، يمكنك استخدام حزمة Network Image Mock ، التي توفر إمكانيات مماثلة لمحاكاة صور الشبكة في اختبارات الأدوات. فيما يلي الخطوات اللازمة لاستخدام هذه الحزمة: https://pub.dev/packages/network_image_mock

الخطوة 1: إضافة الحزمة إلى تبعيات التطوير الخاصة بك
قم بتنفيذ الأمر التالي لإضافة حزمة Network Image Mock إلى مشروعك:

flutter pub add network_image_mock --dev


تأكد من تضمين حزمة Network Image Mock الخاصة dev_dependenciesبك pubspec.yaml:


dev_dependencies:
  network_image_mock: ^2.1.1



الخطوة 2: تحديث اختبار الأداة:
الآن بعد أن قمنا بتثبيت الحزمة، يمكننا تغيير اختبار الأداة الخاص بنا ليبدو بهذا الشكل:


import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:network_image_load_exception/main.dart';
import 'package:network_image_mock/network_image_mock.dart';

void main() {
  testWidgets('Network Image Test', (WidgetTester tester) async {
    await mockNetworkImagesFor(() async => await tester.pumpWidget(
          const MaterialApp(home: HomePage()),
        ));

    Finder image = find.byType(Image);
    Image imageWidget = tester.widget(image);
    NetworkImage networkImageWidget = imageWidget.image as NetworkImage;

    expect(image, findsOneWidget);
    expect(imageWidget.image, isA<NetworkImage>());
    expect(networkImageWidget.url, 'https://picsum.photos/id/182/350/250');
  });
}



التغييرات التي تم إجراؤها على الاختبار الأصلي مشابهة للحل السابق. نبدأ باستيراد حزمة Network Image Mock ونغلف عملية إنشاء الأداة بالوظيفة mockNetworkImagesFor.

من خلال استخدام mockNetworkImagesForالوظيفة التي توفرها Network Image Mock، يمكننا محاكاة صور الشبكة والتأكد من اعتراض مكالمات الشبكة واستبدالها باستجابات محاكاة أثناء اختبار الأداة.



الحل الموصى به لمشكلة NetworkImageLoadException



عند التعامل مع NetworkImageLoadExceptionالخطأ في اختبارات عناصر واجهة المستخدم الرسومية في Flutter، ضع في اعتبارك الاحتياجات المحددة لبيئة الاختبار الخاصة بك. قد يوفر تعطيل تجاوزات HTTP المخصصة للاعتماد على سلوك الشبكات الافتراضي في Flutter حلاً سريعًا، ومع ذلك، يُعتبر هذا ممارسة سيئة. لأن اختباراتك لم تعد معزولة وتعتمد الآن على نظام خارجي. لذلك أوصيك بالذهاب إلى نهج المحاكاة.

لتحسين
التحكم والاختبار المنعزل، فكر في استخدام حزم متخصصة مثل Mocktail Image Network أو Network Image Mock. تتيح لك هذه الحزم محاكاة صور الشبكة ومحاكاة ظروف الشبكة المختلفة.

اختيار الحزمة الصحيحة
لاختيار الحزمة الصحيحة، اختر الحزمة التي تتوافق مع اعتماديات الاختبار الخاصة بك.

  • إذا كنت تستخدم Mocktail لاختبار الأداة، فاستخدم Mocktail Image Network (التي تتضمن Mocktail كاعتمادية).


  • إذا كنت تستخدم Mockito لاختبار الأداة المساعدة، فاستخدم Network Image Mock، (الذي يتضمن Mockito كتبعية).





خاتمة
في هذا المنشور، ناقشنا ثلاث طرق مختلفة لإصلاح خطأ NetworkImageLoadException الذي يحدث عند استخدام Image.networkالأداة في اختبارات أداة Flutter. ناقشنا تعطيل تجاوزات HTTP المخصصة، واستخدام حزمة Mocktail Image Network، واستخدام حزمة Network Image Mock.