Search code examples
dartunit-testingmocking

How can I mock a final class variable in Dart for unit testing?


I'm working on a Dart project where I need to write unit tests for a class that uses a final class variable for making API calls. The class is structured like this:

class MyClass {
  final MyApi _api;

  MyClass(this._api);

  Future<void> myMethod() async {
    final response = await _api.getData();
    // Process the response
  }
}

The MyApi instance is initialized as a final class variable in the constructor, like this:

class MyApi {
  final Dio _dio;

  MyApi(this._dio);

  Future<Response> getData() async {
    return await _dio.get('https://example.com/data');
  }
}

I want to write unit tests for MyClass, but I'm facing a challenge because _api is a final class variable and I can't modify the actual code to inject a mock instance during testing.

Is there a way to mock _api for testing purposes without modifying the original code?


Solution

  • In order to pass a mock instance of the MyApi class to MyClass, pass the mock instance through the MyClass() constructor.

    Like this:

    class MockMyApi implements MyApi {
      MockMyApi(this.expectedData);
    
      final String expectedData;
    
      @override
      Future<String> getData() async {
        return expectedData;
      }
    }
    
    void main() {
      test('MyClass test', () async {
        final mockApi = MockMyApi('Mock data');
        final myClass = MyClass(mockApi);
    
        /// Rest of the test
      });
    }