Search code examples
flutterdartunit-testing

How can unit tests be created for a method that returns a Sealed class as its return value?


How should unit tests for a method that returns a Sealed class like the following be created?

sealed class Result<S, E extends Exception> {
  const Result();
}

final class Success<S, E extends Exception> extends Result<S, E> {
  const Success({required this.value});
  final S value;
}

final class Failure<S, E extends Exception> extends Result<S, E> {
  const Failure({required this.exception});
  final E exception;
}

extension ResultExtension on Result<dynamic, Exception> {
  dynamic get unwrap => switch (this) {
        Success() => (this as Success).value,
        Failure() => throw (this as Failure).exception,
      };
}

When creating and running unit tests for a method that returns a Sealed class, such as the Result class, the following error occurs:

 MissingDummyValueError: Result<void, Exception>
  
  This means Mockito was not smart enough to generate a dummy value of type
  'Result<void, Exception>'. Please consider using either 'provideDummy' or 'provideDummyBuilder'
  functions to give Mockito a proper dummy value.
  
  Please note that due to implementation details Mockito sometimes needs users
  to provide dummy values for some types, even if they plan to explicitly stub
  all the called methods.

I couldn't find anyone creating unit tests for a method that returns a Sealed Class as a return value, even after doing some research. How should unit tests for a method that returns a sealed class as a return value be created?


Solution

    1. First a note on terminology: You aren't unit testing a method that returns a sealed class. To create unit tests for such a method, you simply call that method and verify that its return values match what you expect for given inputs. What you're asking about is how to mock a method that returns a sealed class. That is, the method itself isn't being tested; you're testing other functions to verify how they interact with that method. Your question is about package:mockito, not about unit tests.

    2. The error message tells you what to do: call provideDummy with whatever you want the default value for a Result<void, Exception> to be. Since it's a "dummy" value, the value you choose shouldn't matter. For example:

      @GenerateNiceMocks([...])
      void main() {
        provideDummy(Result<void, Exception>());
      
        // ... Code to run tests...
      }
      

      Also see getting error message for a return value from a mocked function.