@@ -23,6 +23,7 @@ Rultor.com](https://www.rultor.com/b/dartoos-dev/json_cache)](https://www.rultor
2323
2424- [ Overview] ( #overview )
2525- [ Getting Started] ( #getting-started )
26+ - [ Suggested Dependency Relationship] ( #suggested-dependency-relationship )
2627- [ Implementations] ( #implementations )
2728 - [ JsonCacheMem — Thread-safe In-memory cache] ( #jsoncachemem )
2829 - [ JsonCachePrefs — SharedPreferences] ( #jsoncacheprefs )
@@ -32,8 +33,8 @@ Rultor.com](https://www.rultor.com/b/dartoos-dev/json_cache)](https://www.rultor
3233 - [ JsonCacheHive — Hive] ( #jsoncachehive )
3334 - [ JsonCacheCrossLocalStorage — CrossLocalStorage] ( #jsoncachecrosslocalstorage )
3435- [ Unit Test Tips] ( #unit-test-tips )
35- - [ Suggested Dependency Relationship ] ( #suggested-dependency-relationship )
36- - [ Using Fake Implementation ] ( #using-fake-implementation )
36+ - [ Mocking ] ( #mocking )
37+ - [ Fake Implementations ] ( #using-fake-implementation )
3738 - [ Widget Testing] ( #widget-testing )
3839 - [ Example of Widget Test Code] ( #example-of-widget-test-code )
3940 - [ SharedPreferences in Tests] ( #sharedpreferences-in-tests )
@@ -99,7 +100,7 @@ represents the name of a single data group. For example:
99100
100101``` dart
101102'profile': {'name': 'John Doe', 'email': '[email protected] ', 'accountType': 'premium'}; 102- 'preferences': {'theme': {'dark': true}, 'notifications':{'enabled': true}}
103+ 'preferences': {'theme': {'dark': true}, 'notifications': {'enabled': true}}
103104```
104105
105106Above, the _ profile_ key is associated with profile-related data, while
@@ -114,6 +115,39 @@ await jsonCache.refresh('profile', {'name': 'John Doe', 'email': 'johndoe@email.
114115await jsonCache.refresh('preferences', {'theme': {'dark': true}, 'notifications':{'enabled': true}});
115116```
116117
118+ ### Suggested Dependency Relationship
119+
120+ Whenever a function, method, or class needs to interact with cached user data,
121+ it should do so via a reference to the ` JsonCache ` interface.
122+
123+ See the code snippet below:
124+
125+ ``` dart
126+ /// Stores/retrieves user data from the device's local storage.
127+ class JsonCacheRepository implements ILocalRepository {
128+ /// Sets the [JsonCache] instance.
129+ const JsonCacheRepository(this._cache);
130+ // This class depends on an interface rather than any actual implementation
131+ final JsonCache _cache;
132+
133+ /// Retrieves a cached email by [userId] or `null` if not found.
134+ @override
135+ Future<String?> getUserEmail(String userId) async {
136+ final userData = await _cache.value(userId);
137+ if (userData != null) {
138+ // the email value or null if absent.
139+ return userData['email'] as String?;
140+ }
141+ // There is no data associated with [userId].
142+ return null;
143+ }
144+ }
145+ ```
146+
147+ By depending on an interface rather than an actual implementation, your code
148+ becomes [ loosely coupled] ( https://en.wikipedia.org/wiki/Loose_coupling ) to this
149+ package — which makes unit testing a lot easier.
150+
117151## Implementations
118152
119153The library
@@ -269,43 +303,58 @@ is an implementation on top of the
269303This package has been designed with unit testing in mind. This is one of the
270304reasons for the existence of the ` JsonCache ` interface.
271305
272- ### Suggested Dependency Relationship
306+ ### Mocking
273307
274- Whenever a function, method, or class needs to interact with user data, it
275- should do so via a reference to the ` JsonCache ` interface rather than relying on
276- an actual implementation .
308+ Since ` JsonCache ` is the core interface of this package, you can easily
309+ [ mock ] ( https://docs.flutter.dev/cookbook/testing/unit/mocking ) a implementation
310+ that suits you when unit testing your code .
277311
278- See the code snippet below:
312+ For example, with [ mocktail] ( https://pub.dev/packages/mocktail ) a mock
313+ implementation should look like this:
279314
280315``` dart
281- /// Stores/retrieves user data from the device's local storage.
282- class JsonCacheRepository implements ILocalRepository {
283- /// Sets the [JsonCache] instance.
284- const JsonCacheRepository(this._cache);
285- // This class depends on an interface rather than any actual implementation
286- final JsonCache _cache;
316+ import 'package:mocktail/mocktail.dart';
287317
288- /// Retrieves a cached email by [userId] or `null` if not found.
289- @override
290- Future<String?> getUserEmail(String userId) async {
291- final userData = await _cache.value(userId);
292- if (userData != null) {
293- // the email value or null if absent.
294- return userData['email'] as String?;
295- }
296- // There is no data associated with [userId].
297- return null;
298- }
318+ class JsonCacheMock extends Mock implements JsonCache {}
319+
320+ void main() {
321+ // the mock instance.
322+ final jsonCacheMock = JsonCacheMock();
323+
324+ test('should retrieve the preferences data', () async {
325+ // Stub the 'value' method.
326+ when(() => jsonCacheMock.value('preferences')).thenAnswer(
327+ (_) async => <String, dynamic>{
328+ 'theme': {'dark': true},
329+ 'notifications': {'enabled': true}
330+ },
331+ );
332+
333+ // Verify no interactions have occurred.
334+ verifyNever(() => jsonCacheMock.value('preferences'));
335+
336+ // Interact with the jsonCacheMock instance.
337+ final preferencesData = await jsonCacheMock.value('preferences');
338+
339+ // Assert
340+ expect(
341+ preferencesData,
342+ equals(
343+ <String, dynamic>{
344+ 'theme': {'dark': true},
345+ 'notifications': {'enabled': true}
346+ },
347+ ),
348+ );
349+
350+ // Check if the interaction occurred only once.
351+ verify(() => jsonCacheMock.value('preferences')).called(1);
352+ });
299353}
300- ```
301354
302- By depending on an interface rather than an actual implementation, the code
303- above is [ loosely coupled] ( https://en.wikipedia.org/wiki/Loose_coupling ) to this
304- package — which means it's easy to test as you can
305- [ mock] ( https://docs.flutter.dev/cookbook/testing/unit/mocking ) the ` JsonCache `
306- dependency.
355+ ```
307356
308- ### Using Fake Implementation
357+ ### Fake Implementations
309358
310359In addition to mocking, there is another approach to unit testing: making use of
311360a 'fake' implementation. Usually this so called 'fake' implementation provides
0 commit comments