Created
March 25, 2025 12:39
-
-
Save tomaszpolanski/abd4725d4e07ba637d5540b5fe10aa1e to your computer and use it in GitHub Desktop.
ArrangeBuilder and test mixins for Dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'example.dart'; | |
import 'package:mocktail/mocktail.dart'; | |
/// An example of a mixing that needs to be implemented once and can be used | |
/// in multiple tests without doing `when(() => ...)` in every test file | |
mixin ApiMixin { | |
Api api = _MockApi(); | |
/// Function that prepares the mixin to be in a usable state. | |
/// This would be mixin's constructor if mixins would support constructor | |
void arrangeApi() { | |
withApiSuccess(); | |
} | |
void withApiSuccess([String? message]) { | |
when(() => api.fetch(any())).thenAnswer((_) async => message ?? 'empty'); | |
} | |
void withApiError() { | |
when(() => api.fetch(any())).thenThrow(Exception('some exception')); | |
} | |
} | |
class _MockApi extends Mock implements Api {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class ExampleUsecase { | |
ExampleUsecase({required Api api}) : _api = api; | |
final Api _api; | |
Future<String> fetchMessage() async { | |
try { | |
final message = await _api.fetch(42); | |
return message; | |
} catch (_) { | |
return 'Something went wrong'; | |
} | |
} | |
} | |
/// Api that fetches some data. For testing [ExampleUsecase] we do not need | |
/// to have a concrete implementation as we are testing behavior of [ExampleUsecase] | |
abstract class Api { | |
Future<String> fetch(int id); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'api_mixin.dart'; | |
import 'example.dart'; | |
import 'package:mocktail/mocktail.dart'; | |
import 'package:test/test.dart'; | |
late _ArrangeBuilder _builder; | |
void main() { | |
setUp(() { | |
_builder = _ArrangeBuilder(); | |
}); | |
test('returns error message when failed', () async { | |
_builder.withApiError(); | |
final tested = _builder.build(); | |
final result = await tested.fetchMessage(); | |
expect(result, 'Something went wrong'); | |
}); | |
test('returns message message when successful', () async { | |
const expected = 'some message'; | |
_builder.withApiSuccess(expected); | |
final tested = _builder.build(); | |
final result = await tested.fetchMessage(); | |
expect(result, expected); | |
}); | |
test('calls api with a specific id', () async { | |
const expected = 42; | |
final tested = _builder.build(); | |
await tested.fetchMessage(); | |
verify(() => _builder.api.fetch(expected)).called(1); | |
}); | |
} | |
/// ArrangeBuilder can use multiple mixins | |
class _ArrangeBuilder with ApiMixin { | |
_ArrangeBuilder() { | |
arrangeApi(); | |
} | |
ExampleUsecase build() => ExampleUsecase(api: api); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment