How to mock Flutter Fire Firebase Functions correctly?

213

I was able to make your example work with cloud_function-2.0.0 with three small changes.

  1. Adding the <T> type parameters in HttpsCallableMock.call and HttpsCallableResultMock.

  2. Replacing the override of getHttpsCallable with httpsCallable.

  3. Checking parameters?.isNotEmpty == true instead != null. This change might not be needed depending on the behavior you want when empty params are passed.

Here is the updated code.

import 'package:cloud_functions/cloud_functions.dart';
import 'package:mockito/mockito.dart';

class MockFirebaseFunctions extends Mock implements FirebaseFunctions {
  final Map<String, String> _jsonStore = <String, String>{};

  String _convertMapToJson(Map<String, dynamic> parameters) {
    return json.encode(parameters);
  }

  void mockResult(
      {String functionName, String json, Map<String, dynamic> parameters}) {
    if (parameters?.isNotEmpty == true) {
      functionName = functionName + _convertMapToJson(parameters);
    }
    _jsonStore[functionName] = json;
  }

  String getMockResult(String functionName, Map<String, dynamic> parameters) {
    // ignore: parameter_assignments
    functionName = parameters == null
        ? functionName
        : (parameters?.isNotEmpty == true
        ? functionName + _convertMapToJson(parameters)
        : functionName);
    assert(
    _jsonStore[functionName] != null, 'No mock result for $functionName. \n Expected one of ${_jsonStore.keys}');
    return _jsonStore[functionName];
  }

  @override
  HttpsCallable httpsCallable(String functionName, {HttpsCallableOptions options}) {
    return HttpsCallableMock._(this, functionName);
  }
}

class HttpsCallableMock extends Mock implements HttpsCallable {
  HttpsCallableMock._(this._firebaseFunctions, this._functionName);

  final MockFirebaseFunctions _firebaseFunctions;
  final String _functionName;

  @override
  Future<HttpsCallableResult<T>> call<T>([dynamic parameters]) {
    final decoded = json.decode(_firebaseFunctions.getMockResult(
        _functionName, parameters as Map<String, dynamic>));
    return Future.value(HttpsCallableResultMock<T>._(decoded));
  }

  /// The timeout to use when calling the function. Defaults to 60 seconds.
  Duration timeout;
}

class HttpsCallableResultMock<T> extends Mock implements HttpsCallableResult<T> {
  HttpsCallableResultMock._(this.data);

  /// Returns the data that was returned from the Callable HTTPS trigger.
  @override
  final T data;
}

Share:
213
Migalv
Author by

Migalv

Recently graduated software developer. Still learning a lot but knows quite a bunch too. Always looking to improve but also wanted to give a little to the community since it has helped him a lot. Good at: Any object oriented programming Specially Flutter Some planning, management &amp; organization

Updated on December 25, 2022

Comments

  • Migalv
    Migalv over 1 year

    I'm trying to mock the Firebase Functions package from Flutter Fire, but I keep getting errors.

    This is my attempt at creating the Mock. But the call function is giving me errors when I try to override it because the return type is not correct.

    library firebase_cloud_functions_mock;
    
    import 'dart:convert';
    
    import 'package:cloud_functions/cloud_functions.dart';
    import 'package:mockito/mockito.dart';
    
    class MockFirebaseFunctions extends Mock implements FirebaseFunctions {
      final Map<String, String> _jsonStore = <String, String>{};
    
      String _convertMapToJson(Map<String, dynamic> parameters) {
        return json.encode(parameters);
      }
    
      void mockResult(
          {String functionName, String json, Map<String, dynamic> parameters}) {
        if (parameters?.isNotEmpty != null) {
          // ignore: parameter_assignments
          functionName = functionName + _convertMapToJson(parameters);
        }
        _jsonStore[functionName] = json;
      }
    
      String getMockResult(String functionName, Map<String, dynamic> parameters) {
        // ignore: parameter_assignments
        functionName = parameters == null
            ? functionName
            : (parameters?.isNotEmpty != null
                ? functionName + _convertMapToJson(parameters)
                : functionName);
        assert(
            _jsonStore[functionName] != null, 'No mock result for $functionName');
        return _jsonStore[functionName];
      }
    
      @override
      HttpsCallable getHttpsCallable({String functionName}) {
        return HttpsCallableMock._(this, functionName);
      }
    }
    
    class HttpsCallableMock extends Mock implements HttpsCallable {
      HttpsCallableMock._(this._firebaseFunctions, this._functionName);
    
      final MockFirebaseFunctions _firebaseFunctions;
      final String _functionName;
    
      @override
      Future<HttpsCallableResult> call([dynamic parameters]) {
        final decoded = json.decode(_firebaseFunctions.getMockResult(
            _functionName, parameters as Map<String, dynamic>));
        return Future.value(HttpsCallableResultMock._(decoded));
      }
    
      /// The timeout to use when calling the function. Defaults to 60 seconds.
      Duration timeout;
    }
    
    class HttpsCallableResultMock extends Mock implements HttpsCallableResult {
      HttpsCallableResultMock._(this.data);
    
      /// Returns the data that was returned from the Callable HTTPS trigger.
      @override
      final dynamic data;
    }
    

    Does anyone know how to correctly mock the Firebase Functions package from Flutter Fire?