Canales de método de prueba: la aplicación no responde

Foto de Charles Forerunner en Unsplash

Introducción

Como vimos en la entrada anterior, canales de método Permítanos llamar al código nativo desde una aplicación de Flutter. Desde una perspectiva de prueba, los canales de métodos pueden plantear inicialmente un desafío: ¿cómo los rompemos? fuerte dependencia de la plataforma nativa para obtener nuestro código en platos de prueba? Afortunadamente para nosotros, Flutter incluye algunas características integradas que hacen que la prueba de canales de métodos sea muy sencilla.

Función de ejemplo con un canal de método

Supongamos que tenemos uno clase de ayudante en nuestro proyecto que abre las tiendas de aplicaciones correspondientes para que el usuario pueda actualizar la aplicación. El reenvío a la tienda se implementa como un enlace web, que es administrado por url_launcher Complemento de aleteo. Debajo del capó, este complemento utiliza canales de método para manejar los enlaces en el nivel de la plataforma nativa. Una implementación muy simple para esta clase sería algo como: import ‘package:url_launcher/url_launcher.dart’; Class AppStoreLauncherException implementa Exception { final String msg; const AppStoreLauncherException(this.msg): super(); } Clase Lanzador de la tienda de aplicaciones { const AppStoreLauncher() : super(); Futuros launchWebStore({bool isAndroid = true}) async { String url=»https://apps.apple.com/…»; si (es Android) { url=»https://play.google.com/store/apps/details?id=…»; } si (espera puedeLanzamiento(url)) { esperar empezar(dirección URL); } else { throw AppStoreLauncherException(‘No se pudo iniciar $url’); } } } Tenga en cuenta que son los métodos canLaunch() y launch() proporcionado por el complemento. Si queremos probar esta clase, necesitamos simular los valores que devuelve. Veamos cómo va…

flujo de trabajo

Con el fin de Simular un canal de método:

  1. Cree un canal de método «falso» con el mismo nombre único
  2. Registre un controlador para interceptar llamadas a código nativo
  3. Stub los valores devueltos de las llamadas en nuestro canal de método «falso»
  4. Agregue algunas «variables de detección» opcionales.

1. Crear un canal falso

Instanciar un nuevo objeto, pasando como parámetro el nombre del canal que queremos simular. Debido a que los nombres deben ser únicos, generalmente se ven como un nombre de paquete invertido. En el ejemplo actual, necesitamos usar el nombre del complemento del iniciador de URL: MethodChannel mockChannel = const MétodoChannel(‘plugins.flutter.io/url_launcher’);

2. Registro del manipulador

Toda la información intercambiada entre Flutter y la plataforma nativa se guarda como un mensaje. Si queremos controlar los valores intercambiados, necesitamos usar el mixin «TestDefaultBinaryMessengerBinding». La clase anterior delega las funciones de mensajería a una propiedad llamada defaultBinaryMessenger: así que este es el objeto que necesitamos usar para tomar el control de los mensajes intercambiados. La API TestDefaultBinaryMessenger nos permite simular las llamadas de código nativo usando setMockMethodCallHandler(): TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMethodCallHandler(MockChannel, Manejador); Este método toma como argumentos:

  • el falso» canal de método
  • Una función manipuladores que hace el stubing real para los valores devueltos. Simplemente examina el método llamado (pasado como parámetro) y devuelve el valor que preferimos para esa llamada

Así que todos juntos: Futuro? manipuladores(MethodCall methodCall) async { if (methodCall.method == «canLaunch») { return true; } falso retorno; } TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMethodCallHandler(mockChannel, manipuladores);

3. Valores de resguardo

Dado que el enfoque anterior no es muy flexible, podemos envolver el código en un método personalizado el cual toma como parámetros opcionales los valores de retorno que queremos usar y registra el manejador con ellos. Esto nos permite controlar el canal «incorrecto» en tiempo de ejecución: vacío _mockChannelValues({bool canLaunch = true, bool launch = true}) { TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger .setMockMethodCallHandler( mockChannel, (MethodCall methodCall) async { if (methodCall.method == «canLaunch») { return canLaunch; } else if ( methodCall.method == «launch») { return launch; } return false; } ); }

4. Adición de «variables de detección» opcionales

Las «variables de detección» son básicamente propiedades redundantes que le dan una mejor información a través de un fragmento de código. Aunque generalmente se agregan en el código de producción, también podemos usarlos en el código de prueba para averiguar qué sucede debajo del capó. En este caso podemos iniciar sesión/Registrar cada llamada realizada en nuestro canal de método «falso» con una variable de medición. Más tarde, podemos revisar estos registros para asegurarnos de que todo salió como se esperaba y hacer algunas afirmaciones. Finalmente, solo necesitamos declarar una nueva variable: lista tardíaregistro falso; y cámbielo cada vez que se llama a un método: void _mockChannelValues({bool canLaunch = true, bool launch = true}) { TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger .setMockMethodCallHandler( mockChannel, (MethodCall methodCall) async {
fakeLog.add(llamadamétodo);

//XXX: más código aquí… } ); } Posteriormente podemos comprobar su contenido buscando un método específico o número de llamadas: Expect(fakeLog.length, 2); Expect( fakeLog.map((e) => e.method), equals([
‘canLaunch’,
‘launch’,
]));

Bonificación: prueba de unidad de muestra

Prueba si el Android PlayStore se lanza en realidad usando nuestra clase de ayuda: prueba (‘Cuando se invoca la tienda de Android canLaunch y el lanzamiento’, () async {
_mockChannelValues(canLaunch: verdadero, Inicio: verdadero); espere launcher.launchWebStore (isAndroid: true);

suponer(fakeLog.longitud, 2);
suponer( fakeLog.map((e) => e.método), equals([
‘canLaunch’,
‘launch’,
])); });

Solución de problemas

Dado que estamos simulando el uso de bibliotecas de terceros, código nativo, etc., debemos asegurarnos de que el El entorno de prueba de Flutter está configurado correctamente antes de ejecutar las pruebas, de lo contrario nos encontraremos con un error desagradable. Así que asegúrate de llamar:

TestWidgetsFlutterBinding.ensureInitialized(); antes de ejecutar sus pruebas

Código de muestra

Como siempre, Código fuente está disponible aquí. ¡Escríbeme la próxima vez!

Como esto:

Me gusta Cargando…

Relacionado

Deja una respuesta

Tu dirección de correo electrónico no será publicada.