Flutter Arquitectura Limpia [7] – Información de Red

flutterclean7
Compartir

Flutter Arquitectura Limpia [7] – Información de Red

 

Ahora que tenemos implementada la implementación del Repositorio, vamos a implementar sus dependencias, comenzando con la clase NetworkInfo utilizada para averiguar si el dispositivo está actualmente conectado a una red. Esta parte es donde finalmente haremos un desarrollo basado en pruebas con paquetes de terceros, lo que significa que vamos a burlarnos de las clases de terceros.

Debo aclarar que el contenido original es de Resocoder,  lo que he hecho  es una traducción al español del contenido. Al final de este artículo está el video en inglés para que vayan ilustrándose mejor y ya tengan una claridad de lo expuesto

Curso TDD Arquitectura Limpia

Esta publicación es solo una parte de una serie de tutoriales.  Como siempre, ya sabemos cómo se ve la interfaz de NetworkInfo, porque primero definimos su contrato. Tiene una sola propiedad llamada isConnected.

network_info.dart

abstract class NetworkInfo {
  Future<bool> get isConnected;
}

Cambiando paquetes

En la segunda parte, le dije que usaremos el paquete de connectivity para conocer el estado de la red. Si bien ese paquete es útil para determinar si el dispositivo se está ejecutando en datos móviles o en WiFi, descubrí que no es tan bueno verificar si hay un acceso real a Internet. Como se escribe directamente en la página del paquete:

Tenga en cuenta que en Android, esto no garantiza la conexión a Internet. Por ejemplo, la aplicación podría tener acceso a WiFi pero podría ser una VPN o un WiFi de hotel sin acceso a Internet.

Como no podemos confiar únicamente en la información que proporciona la plataforma (Android / iOS), ¿en qué podemos confiar? En realidad conectando a algo, por supuesto! El paquete data_connection_checker es perfecto para eso.

 

 

pubspec.yaml

dependencies:
  # Swap the connectivity package for this
  data_connection_checker: ^0.3.4

Esto abre un socket a ciertas direcciones y determina el estado de la conexión real en función de si realmente puede conectarse. Además, es completamente independiente de la plataforma, ¡también puede funcionar en la web!

Las direcciones utilizadas apuntan a los servidores DNS de CloudFlare, Google y OpenDNS. Digamos que estos tres servicios combinados tienen un tiempo de actividad del 100%, por lo que no se preocupe si el estado en línea del dispositivo se determinará de manera veraz.

Ahora que sabemos que no usaremos el paquete connectivity porque obtener información de conexión de la plataforma no es confiable, solo es conveniente cambiar el nombre de la carpeta core/platform a core/network. También tendremos que arreglar las importaciones en la implementación y prueba del repositorio.

Implementación

Primero creemos un archivo de prueba en una ubicación reflejada como de costumbre. Aunque no habrá mucha lógica para realizar, es importante no soltar TDD incluso en tales casos. Los errores se pueden ocultar incluso en un código aparentemente inocuo.

Test “mirrored” location

La clase NetworkInfo debería incluir una instancia de DataConnectionChecker en su constructor y, por supuesto, vamos a crear un mock. La prueba real de la propiedad isConnected será un poco diferente de las pruebas que hemos escrito hasta ahora …

network_info_test.dart

import 'package:clean_architecture_tdd_prep/core/network/network_info.dart';
import 'package:data_connection_checker/data_connection_checker.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/mockito.dart';

class MockDataConnectionChecker extends Mock implements DataConnectionChecker {}

void main() {
  NetworkInfoImpl networkInfo;
  MockDataConnectionChecker mockDataConnectionChecker;

  setUp(() {
    mockDataConnectionChecker = MockDataConnectionChecker();
    networkInfo = NetworkInfoImpl(mockDataConnectionChecker);
  });

  group('isConnected', () {
    test(
      'should forward the call to DataConnectionChecker.hasConnection',
      () async {
        // arrange
        final tHasConnectionFuture = Future.value(true);

        when(mockDataConnectionChecker.hasConnection)
            .thenAnswer((_) => tHasConnectionFuture);
        // act
        // NOTICE: We're NOT awaiting the result
        final result = networkInfo.isConnected;
        // assert
        verify(mockDataConnectionChecker.hasConnection);
        // Utilizing Dart's default referential equality.
        // Only references to the same object are equal.
        expect(result, tHasConnectionFuture);
      },
    );
  });
}

 

Llamar a NetworkInfo (). IsConnected es realmente solo un apodo para llamar a DataConnectionChecker (). HasConnection. Simplemente estamos ocultando la biblioteca de terceros detrás de una interfaz de nuestra propia clase. Podemos verificar si la llamada a la propiedad se “reenvía” verificando si el objeto Future devuelto por isConnected es exactamente el mismo que el devuelto por hasConnection.

Puede parecer que tal “desvío de llamadas” es solo una pérdida de esfuerzo. ¡Todo lo contrario!

Imagine que desea cambiar el paquete data_connection_checker por algo diferente. Si lo usó directamente dentro de los repositorios (a menos que esté construyendo una aplicación Number Trivia, tendrá varias), necesitaría cambiar MUCHO código de verificación de conectividad.

Al ocultarlo detrás de una interfaz que controlas, ¡no habrá mucho código para cambiar en absoluto!

La implementación es simple entonces. No vamos a crear un archivo separado para él, sino que lo colocamos directamente debajo de la definición de clase abstracta.

network_info.dart

import 'package:data_connection_checker/data_connection_checker.dart';

abstract class NetworkInfo {
  Future<bool> get isConnected;
}

class NetworkInfoImpl implements NetworkInfo {
  final DataConnectionChecker connectionChecker;

  NetworkInfoImpl(this.connectionChecker);

  @override
  Future<bool> get isConnected => connectionChecker.hasConnection;
}

¿Qué sigue?

Si bien es posible que esta parte no haya sido la más larga, hay mucho que asimilar. Implementamos la clase NetworkInfo con un enfoque de prueba interesante y aprendiste por qué es beneficioso crear incluso clases aparentemente “inútiles” solo para ocultar código de terceros en un entorno estable.

Todavía hay fuentes de datos para implementar. En la siguiente parte, vamos a trabajar en la fuente de datos local, lo que significa hacer TDD con el paquete shared_preferences.

 

 

 

 

Aquí les comparto el video


Compartir

Entradas relacionadas

Deja tu comentario