Skip to content

Commit 8d977e3

Browse files
committed
Add Dependency Inversion Principle (DIP) example (2.1/3)
* Add the second iteration of the second stage of our code. Now the `HardcodedInMemoryUsersRepository` will also have its `users` map injected through its constructor. Benefits explained in the test code.
1 parent 84fccb9 commit 8d977e3

File tree

4 files changed

+87
-3
lines changed

4 files changed

+87
-3
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package tv.codely.solid_principles.dependency_inversion_principle.stage_2_1_dependency_injection_of_constant_parameters;
2+
3+
import tv.codely.solid_principles.dependency_inversion_principle.User;
4+
5+
import java.util.Map;
6+
import java.util.Optional;
7+
8+
final class HardcodedInMemoryUsersRepository {
9+
private Map<Integer, User> users;
10+
11+
public HardcodedInMemoryUsersRepository(Map<Integer, User> users) {
12+
this.users = users;
13+
}
14+
15+
public Optional<User> search(Integer id) {
16+
return Optional.ofNullable(users.get(id));
17+
}
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package tv.codely.solid_principles.dependency_inversion_principle.stage_2_1_dependency_injection_of_constant_parameters;
2+
3+
import tv.codely.solid_principles.dependency_inversion_principle.User;
4+
5+
import java.util.Optional;
6+
7+
final class UserSearcher {
8+
private HardcodedInMemoryUsersRepository usersRepository;
9+
10+
public UserSearcher(HardcodedInMemoryUsersRepository usersRepository) {
11+
this.usersRepository = usersRepository;
12+
}
13+
14+
public Optional<User> search(Integer id) {
15+
return usersRepository.search(id);
16+
}
17+
}

src/test/java/tv/codely/solid_principles/dependency_inversion_principle/stage_1_instantiating_from_clients/UserSearcherShould.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,21 +10,21 @@
1010
final class UserSearcherShould {
1111
@Test
1212
void find_existing_users() {
13+
UserSearcher userSearcher = new UserSearcher();
14+
1315
// We would be coupled to the actual HardcodedInMemoryUsersRepository implementation.
1416
// We don't have the option to set test users as we would have to do if we had a real database repository.
1517
Integer existingUserId = 1;
16-
UserSearcher userSearcher = new UserSearcher();
17-
1818
Optional<User> expectedUser = Optional.of(new User(1, "Rafa"));
1919

2020
assertEquals(expectedUser, userSearcher.search(existingUserId));
2121
}
2222

2323
@Test
2424
void not_find_non_existing_users() {
25-
Integer nonExistingUserId = 5;
2625
UserSearcher userSearcher = new UserSearcher();
2726

27+
Integer nonExistingUserId = 5;
2828
Optional<User> expectedEmptyResult = Optional.empty();
2929

3030
assertEquals(expectedEmptyResult, userSearcher.search(nonExistingUserId));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package tv.codely.solid_principles.dependency_inversion_principle.stage_2_1_dependency_injection_of_constant_parameters;
2+
3+
import org.junit.jupiter.api.Test;
4+
import tv.codely.solid_principles.dependency_inversion_principle.User;
5+
6+
import java.util.Collections;
7+
import java.util.HashMap;
8+
import java.util.Map;
9+
import java.util.Optional;
10+
11+
import static org.junit.jupiter.api.Assertions.assertEquals;
12+
13+
final class UserSearcherShould {
14+
@Test
15+
void find_existing_users() {
16+
// Now we're also injecting the constant parameters needed by the HardcodedInMemoryUsersRepository through its constructor.
17+
// 👍 Win: We can send different parameters depending on the environment.
18+
// That is, in our production environment we would have actual users,
19+
// while in our tests cases we will set only the needed ones to run our test cases
20+
int rafaId = 1;
21+
User rafa = new User(rafaId, "Rafa");
22+
23+
Map<Integer, User> users = Collections.unmodifiableMap(new HashMap<Integer, User>() {
24+
{
25+
put(rafaId, rafa);
26+
}
27+
});
28+
HardcodedInMemoryUsersRepository usersRepository = new HardcodedInMemoryUsersRepository(users);
29+
UserSearcher userSearcher = new UserSearcher(usersRepository);
30+
31+
Optional<User> expectedUser = Optional.of(rafa);
32+
33+
assertEquals(expectedUser, userSearcher.search(rafaId));
34+
}
35+
36+
@Test
37+
void not_find_non_existing_users() {
38+
Map<Integer, User> users = Collections.emptyMap();
39+
HardcodedInMemoryUsersRepository usersRepository = new HardcodedInMemoryUsersRepository(users);
40+
UserSearcher userSearcher = new UserSearcher(usersRepository);
41+
42+
// 👍 Win: Now we don't have to be coupled of the actual HardcodedInMemoryUsersRepository users.
43+
// We can send a random user ID in order to force an empty result because we've set an empty map as the system users.
44+
Integer nonExistingUserId = 1;
45+
Optional<User> expectedEmptyResult = Optional.empty();
46+
47+
assertEquals(expectedEmptyResult, userSearcher.search(nonExistingUserId));
48+
}
49+
}

0 commit comments

Comments
 (0)