Skip to content

Commit 258ed48

Browse files
committed
feat: add mock classes and context helper
- Created mock classes for deps - Added context helper for tests
1 parent 159be74 commit 258ed48

File tree

2 files changed

+125
-0
lines changed

2 files changed

+125
-0
lines changed
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import 'package:dart_frog/dart_frog.dart';
2+
import 'package:ht_api/src/registry/model_registry.dart'; // For RequestId
3+
import 'package:ht_api/src/services/auth_service.dart'; // Import necessary types
4+
import 'package:ht_data_repository/ht_data_repository.dart'; // For HtDataRepository
5+
import 'package:ht_shared/ht_shared.dart'; // For User
6+
import 'package:mocktail/mocktail.dart';
7+
import 'package:test/test.dart'; // Import for TypeMatcher and isA
8+
9+
import '../../routes/_middleware.dart'; // Import for RequestId
10+
import 'mock_classes.dart'; // Import your mock classes
11+
12+
/// Creates a mock [RequestContext] with specified dependencies and request.
13+
///
14+
/// Simplifies setting up context for route handler tests.
15+
RequestContext createMockRequestContext({
16+
Request? request,
17+
Map<Type, dynamic> dependencies = const {},
18+
}) {
19+
final context = MockRequestContext();
20+
final effectiveRequest =
21+
request ?? MockRequest(); // Use provided or mock request
22+
23+
// Stub the request getter
24+
when(() => context.request).thenReturn(effectiveRequest);
25+
26+
// Stub the read<T>() method for each provided dependency.
27+
// Use specific types for clarity and type safety.
28+
dependencies.forEach((type, instance) {
29+
// Add specific stubs for known types. Extend this list as needed.
30+
if (type == AuthService) {
31+
when(() => context.read<AuthService>()).thenReturn(instance as AuthService);
32+
} else if (type == HtDataRepository<User>) {
33+
when(() => context.read<HtDataRepository<User>>())
34+
.thenReturn(instance as HtDataRepository<User>);
35+
} else if (type == RequestId) {
36+
// Handle RequestId specifically if provided
37+
when(() => context.read<RequestId>()).thenReturn(instance as RequestId);
38+
}
39+
// Add other common types here...
40+
// Example for another repository type:
41+
// else if (type == HtDataRepository<Headline>) {
42+
// when(() => context.read<HtDataRepository<Headline>>())
43+
// .thenReturn(instance as HtDataRepository<Headline>);
44+
// }
45+
else {
46+
// Attempt a generic stub for other types, but warn if it fails.
47+
// Using `any()` in read is generally discouraged, prefer specific types.
48+
print(
49+
'Warning: Attempting generic stub for context.read<$type>. '
50+
'Consider adding a specific stub in createMockRequestContext.',
51+
);
52+
// This generic stub might not always work as expected.
53+
// Use a specific type if possible, otherwise fallback carefully.
54+
try {
55+
// Stubbing read<dynamic>() can be tricky. Prefer specific types.
56+
// If absolutely needed, ensure the call signature matches.
57+
// Mocktail's `any` matcher doesn't take arguments for `read`.
58+
when(() => context.read<dynamic>()).thenReturn(instance);
59+
} catch (e) {
60+
print('Failed to setup generic read stub for $type: $e');
61+
}
62+
}
63+
});
64+
65+
// Provide a fallback for read<T>() for types *not* explicitly provided.
66+
// This helps catch errors in test setup.
67+
// Corrected: `any()` doesn't take arguments here.
68+
when(() => context.read<dynamic>()).thenThrow(
69+
Exception(
70+
'Dependency not found in mock context. '
71+
'Ensure all required dependencies are provided in the test setup.',
72+
),
73+
);
74+
75+
// Stub provide<T>(). It expects a function that returns the value.
76+
// We match any function using `any()` and return the same context
77+
// to allow chaining, which is typical for provider middleware.
78+
// Corrected: provide takes one argument (the provider function).
79+
// Use `any<T>()` with explicit type argument for the function.
80+
when(() => context.provide<dynamic>(any<dynamic Function()>())).thenReturn(context);
81+
82+
return context;
83+
}
84+
85+
// Removed the incorrect TypeMatcher helper function.
86+
// Use `isA<Type>()` from package:test/test.dart directly if needed.

test/helpers/mock_classes.dart

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import 'package:dart_frog/dart_frog.dart';
2+
import 'package:ht_api/src/services/auth_service.dart';
3+
import 'package:ht_api/src/services/auth_token_service.dart';
4+
import 'package:ht_api/src/services/verification_code_storage_service.dart';
5+
import 'package:ht_app_settings_repository/ht_app_settings_repository.dart';
6+
import 'package:ht_data_repository/ht_data_repository.dart';
7+
import 'package:ht_email_repository/ht_email_repository.dart';
8+
import 'package:ht_shared/ht_shared.dart';
9+
import 'package:mocktail/mocktail.dart';
10+
import 'package:uuid/uuid.dart';
11+
12+
// Core Dart Frog Mocks
13+
class MockRequestContext extends Mock implements RequestContext {}
14+
class MockRequest extends Mock implements Request {}
15+
class MockResponse extends Mock implements Response {}
16+
class MockUri extends Mock implements Uri {}
17+
18+
// Service Mocks
19+
class MockAuthService extends Mock implements AuthService {}
20+
class MockAuthTokenService extends Mock implements AuthTokenService {}
21+
class MockVerificationCodeStorageService extends Mock
22+
implements VerificationCodeStorageService {}
23+
24+
// Repository Mocks
25+
class MockHtDataRepository<T> extends Mock implements HtDataRepository<T> {}
26+
class MockUserRepository extends MockHtDataRepository<User> {}
27+
class MockHeadlineRepository extends MockHtDataRepository<Headline> {}
28+
class MockCategoryRepository extends MockHtDataRepository<Category> {}
29+
class MockSourceRepository extends MockHtDataRepository<Source> {}
30+
class MockCountryRepository extends MockHtDataRepository<Country> {}
31+
// Corrected: Use 'extends Mock implements' for concrete classes
32+
class MockAppSettingsRepository extends Mock implements HtAppSettingsRepository {}
33+
class MockEmailRepository extends Mock implements HtEmailRepository {}
34+
35+
// Utility Mocks
36+
class MockUuid extends Mock implements Uuid {}
37+
38+
// You can add more specific repository mocks if needed, e.g.:
39+
// class MockUserRepository extends Mock implements HtDataRepository<User> {}

0 commit comments

Comments
 (0)