├── .gitignore
├── .idea
├── compiler.xml
├── encodings.xml
├── misc.xml
└── vcs.xml
├── pom.xml
└── src
├── main
├── java
│ └── com
│ │ └── vincent
│ │ └── demo
│ │ ├── Application.java
│ │ ├── config
│ │ └── CacheConfig.java
│ │ ├── log
│ │ ├── QueryHistory.java
│ │ └── QueryHistoryService.java
│ │ ├── model
│ │ ├── LikePO.java
│ │ ├── PostPO.java
│ │ ├── PostVO.java
│ │ └── UserPO.java
│ │ └── service
│ │ ├── LikeService.java
│ │ ├── PostService.java
│ │ └── UserService.java
└── resources
│ └── application.properties
└── test
├── java
└── com
│ └── vincent
│ └── demo
│ └── CacheTests.java
└── resources
└── application.properties
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | /.idea
3 | /target
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | org.springframework.boot
7 | spring-boot-starter-parent
8 | 3.1.2
9 |
10 |
11 | com.vincent
12 | demo
13 | 0.0.1-SNAPSHOT
14 | demo
15 | Demo project for Spring Boot
16 |
17 | 17
18 |
19 |
20 |
21 | org.springframework.boot
22 | spring-boot-starter-web
23 |
24 |
25 |
26 | org.springframework.boot
27 | spring-boot-starter-test
28 | test
29 |
30 |
31 |
32 | junit
33 | junit
34 |
35 |
36 |
37 | org.springframework.boot
38 | spring-boot-starter-data-redis
39 |
40 |
41 |
42 |
43 |
44 |
45 | org.springframework.boot
46 | spring-boot-maven-plugin
47 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/src/main/java/com/vincent/demo/Application.java:
--------------------------------------------------------------------------------
1 | package com.vincent.demo;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 | import org.springframework.cache.annotation.EnableCaching;
6 |
7 | @SpringBootApplication
8 | @EnableCaching
9 | public class Application {
10 |
11 | public static void main(String[] args) {
12 | SpringApplication.run(Application.class, args);
13 | }
14 |
15 | }
--------------------------------------------------------------------------------
/src/main/java/com/vincent/demo/config/CacheConfig.java:
--------------------------------------------------------------------------------
1 | package com.vincent.demo.config;
2 |
3 | import org.springframework.cache.CacheManager;
4 | import org.springframework.context.annotation.Bean;
5 | import org.springframework.context.annotation.Configuration;
6 | import org.springframework.data.redis.cache.RedisCacheConfiguration;
7 | import org.springframework.data.redis.cache.RedisCacheManager;
8 | import org.springframework.data.redis.connection.RedisConnectionFactory;
9 | import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
10 | import org.springframework.data.redis.serializer.RedisSerializationContext;
11 |
12 | import java.time.Duration;
13 |
14 | @Configuration
15 | public class CacheConfig {
16 |
17 | @Bean
18 | public CacheManager redisCacheManager(RedisConnectionFactory connectionFactory) {
19 | var serializer = new GenericJackson2JsonRedisSerializer();
20 | var config = RedisCacheConfiguration.defaultCacheConfig()
21 | .entryTtl(Duration.ofMinutes(10))
22 | .serializeValuesWith(
23 | RedisSerializationContext.SerializationPair.fromSerializer(
24 | serializer));
25 | return RedisCacheManager.builder(connectionFactory)
26 | .cacheDefaults(config)
27 | .build();
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/main/java/com/vincent/demo/log/QueryHistory.java:
--------------------------------------------------------------------------------
1 | package com.vincent.demo.log;
2 |
3 | public class QueryHistory {
4 | private String type;
5 | private String identifier;
6 |
7 | public static QueryHistory of(String type, String identifier) {
8 | var history = new QueryHistory();
9 | history.type = type;
10 | history.identifier = identifier;
11 | return history;
12 | }
13 |
14 | public String getType() {
15 | return type;
16 | }
17 |
18 | public String getIdentifier() {
19 | return identifier;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/main/java/com/vincent/demo/log/QueryHistoryService.java:
--------------------------------------------------------------------------------
1 | package com.vincent.demo.log;
2 |
3 | import org.springframework.stereotype.Service;
4 |
5 | import java.util.ArrayList;
6 | import java.util.List;
7 |
8 | @Service
9 | public class QueryHistoryService {
10 | private final List histories = new ArrayList<>();
11 |
12 | public void add(String type, String identifier) {
13 | histories.add(QueryHistory.of(type, identifier));
14 | }
15 |
16 | public boolean contains(String type, String identifier) {
17 | return histories.stream()
18 | .anyMatch(x -> x.getType().equals(type) && x.getIdentifier().equals(identifier));
19 | }
20 |
21 | public void deleteAll() {
22 | histories.clear();
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/java/com/vincent/demo/model/LikePO.java:
--------------------------------------------------------------------------------
1 | package com.vincent.demo.model;
2 |
3 | import java.util.Objects;
4 |
5 | public class LikePO {
6 | private String userId;
7 | private String postId;
8 |
9 | public static LikePO of(String userId, String postId) {
10 | var like = new LikePO();
11 | like.userId = userId;
12 | like.postId = postId;
13 |
14 | return like;
15 | }
16 |
17 | public String getUserId() {
18 | return userId;
19 | }
20 |
21 | public String getPostId() {
22 | return postId;
23 | }
24 |
25 | @Override
26 | public int hashCode() {
27 | return Objects.hash(userId, postId);
28 | }
29 |
30 | @Override
31 | public boolean equals(Object o) {
32 | if (this == o) return true;
33 | if (o == null || getClass() != o.getClass()) return false;
34 |
35 | var other = (LikePO) o;
36 | return Objects.equals(userId, other.getUserId()) &&
37 | Objects.equals(postId, other.getPostId());
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/com/vincent/demo/model/PostPO.java:
--------------------------------------------------------------------------------
1 | package com.vincent.demo.model;
2 |
3 | public class PostPO {
4 | private String id;
5 | private String creatorId;
6 | private String title;
7 |
8 | public static PostPO of(String id, String creatorId, String title) {
9 | var post = new PostPO();
10 | post.id = id;
11 | post.creatorId = creatorId;
12 | post.title = title;
13 |
14 | return post;
15 | }
16 |
17 | public String getId() {
18 | return id;
19 | }
20 |
21 | public String getCreatorId() {
22 | return creatorId;
23 | }
24 |
25 | public String getTitle() {
26 | return title;
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/com/vincent/demo/model/PostVO.java:
--------------------------------------------------------------------------------
1 | package com.vincent.demo.model;
2 |
3 | import java.util.List;
4 |
5 | public class PostVO {
6 | private String id;
7 | private String creatorId;
8 | private String title;
9 | private String creatorName;
10 | private List likerNames;
11 |
12 | public static PostVO of(PostPO postPO, String creatorName, List likerNames) {
13 | var postVO = new PostVO();
14 | postVO.id = postPO.getId();
15 | postVO.creatorId = postPO.getCreatorId();
16 | postVO.title = postPO.getTitle();
17 | postVO.creatorName = creatorName;
18 | postVO.likerNames = likerNames;
19 |
20 | return postVO;
21 | }
22 |
23 | public String getId() {
24 | return id;
25 | }
26 |
27 | public String getCreatorId() {
28 | return creatorId;
29 | }
30 |
31 | public String getTitle() {
32 | return title;
33 | }
34 |
35 | public String getCreatorName() {
36 | return creatorName;
37 | }
38 |
39 | public List getLikerNames() {
40 | return likerNames;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/main/java/com/vincent/demo/model/UserPO.java:
--------------------------------------------------------------------------------
1 | package com.vincent.demo.model;
2 |
3 | import java.util.Date;
4 |
5 | public class UserPO {
6 | private String id;
7 | private String name;
8 | private Date createTime;
9 |
10 | public static UserPO of(String id, String name) {
11 | var user = new UserPO();
12 | user.id = id;
13 | user.name = name;
14 | user.createTime = new Date();
15 |
16 | return user;
17 | }
18 |
19 | public String getId() {
20 | return id;
21 | }
22 |
23 | public String getName() {
24 | return name;
25 | }
26 |
27 | public Date getCreateTime() {
28 | return createTime;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/com/vincent/demo/service/LikeService.java:
--------------------------------------------------------------------------------
1 | package com.vincent.demo.service;
2 |
3 | import com.vincent.demo.log.QueryHistoryService;
4 | import com.vincent.demo.model.LikePO;
5 | import org.slf4j.Logger;
6 | import org.slf4j.LoggerFactory;
7 | import org.springframework.beans.factory.annotation.Autowired;
8 | import org.springframework.cache.annotation.CacheEvict;
9 | import org.springframework.cache.annotation.Cacheable;
10 | import org.springframework.cache.annotation.Caching;
11 | import org.springframework.stereotype.Service;
12 |
13 | import java.util.ArrayList;
14 | import java.util.HashSet;
15 | import java.util.List;
16 | import java.util.Set;
17 |
18 | @Service
19 | public class LikeService {
20 | private static final Logger logger = LoggerFactory.getLogger(LikeService.class);
21 |
22 | private final Set likeDB = new HashSet<>();
23 |
24 | @Autowired
25 | private UserService userService;
26 |
27 | @Autowired
28 | private QueryHistoryService historyService;
29 |
30 | @Caching(
31 | evict = {
32 | @CacheEvict(cacheNames = "likeUserNames", key = "#postId"),
33 | @CacheEvict(cacheNames = "likeCount", key = "#p1")
34 | }
35 | )
36 | public void createLike(String userId, String postId) {
37 | var like = LikePO.of(userId, postId);
38 | likeDB.add(like);
39 | }
40 |
41 | @Cacheable(cacheNames = "likeCount", key = "#postId")
42 | public long getLikeCount(String postId) {
43 | logNotReadFromCache("likeCount", postId);
44 | return likeDB.stream()
45 | .filter(like -> like.getPostId().equals(postId))
46 | .count();
47 | }
48 |
49 | @Cacheable(cacheNames = "likeUserNames", key = "#postId")
50 | public List getLikeUserNames(String postId) {
51 | logNotReadFromCache("likeUserNames", postId);
52 |
53 | var userIds = likeDB.stream()
54 | .filter(like -> like.getPostId().equals(postId))
55 | .map(LikePO::getUserId)
56 | .toList();
57 | var userIdToNameMap = userService.getUserIdToNameMap(userIds);
58 | var names = userIds.stream()
59 | .map(userIdToNameMap::get)
60 | .toList();
61 | return new ArrayList<>(names);
62 | }
63 |
64 | public void deleteAll() {
65 | likeDB.clear();
66 | }
67 |
68 | private void logNotReadFromCache(String type, String identifier) {
69 | logger.info("Not read data from cache: {}-{}", type, identifier);
70 | historyService.add(type, identifier);
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/src/main/java/com/vincent/demo/service/PostService.java:
--------------------------------------------------------------------------------
1 | package com.vincent.demo.service;
2 |
3 | import com.vincent.demo.log.QueryHistoryService;
4 | import com.vincent.demo.model.PostPO;
5 | import com.vincent.demo.model.PostVO;
6 | import org.slf4j.Logger;
7 | import org.slf4j.LoggerFactory;
8 | import org.springframework.beans.factory.annotation.Autowired;
9 | import org.springframework.cache.annotation.Cacheable;
10 | import org.springframework.stereotype.Service;
11 |
12 | import java.util.*;
13 |
14 | @Service
15 | public class PostService {
16 | private static final Logger logger = LoggerFactory.getLogger(PostService.class);
17 |
18 | private final Map postDB = new HashMap<>();
19 |
20 | @Autowired
21 | private UserService userService;
22 |
23 | @Autowired
24 | private LikeService likeService;
25 |
26 | @Autowired
27 | private QueryHistoryService historyService;
28 |
29 | public PostPO createPost(String id, String userId, String title) {
30 | var post = PostPO.of(id, userId, title);
31 | postDB.put(post.getId(), post);
32 |
33 | return post;
34 | }
35 |
36 | public PostVO getPost(String id) {
37 | var postPO = postDB.get(id);
38 | var creatorName = userService.getUser(postPO.getCreatorId()).getName();
39 | var likeUserNames = likeService.getLikeUserNames(id);
40 |
41 | return PostVO.of(postPO, creatorName, likeUserNames);
42 | }
43 |
44 | @Cacheable(cacheNames = "post", key = "'mostLikedPosts'")
45 | public List getMostLikedPosts() {
46 | logNotReadFromCache("post", "mostLikedPosts");
47 |
48 | var postToLikeCountMap = new HashMap();
49 | postDB.values()
50 | .forEach(post -> {
51 | var likeCount = likeService.getLikeCount(post.getId());
52 | postToLikeCountMap.put(post.getId(), likeCount);
53 | });
54 |
55 | var posts = postToLikeCountMap.entrySet()
56 | .stream()
57 | .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
58 | .limit(3)
59 | .map(x -> getPost(x.getKey()))
60 | .toList();
61 | return new ArrayList<>(posts);
62 | }
63 |
64 | public void deleteAll() {
65 | postDB.clear();
66 | }
67 |
68 | private void logNotReadFromCache(String type, String identifier) {
69 | logger.info("Not read data from cache: {}-{}", type, identifier);
70 | historyService.add(type, identifier);
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/src/main/java/com/vincent/demo/service/UserService.java:
--------------------------------------------------------------------------------
1 | package com.vincent.demo.service;
2 |
3 | import com.vincent.demo.log.QueryHistoryService;
4 | import com.vincent.demo.model.UserPO;
5 | import org.slf4j.Logger;
6 | import org.slf4j.LoggerFactory;
7 | import org.springframework.beans.factory.annotation.Autowired;
8 | import org.springframework.cache.annotation.CachePut;
9 | import org.springframework.cache.annotation.Cacheable;
10 | import org.springframework.stereotype.Service;
11 |
12 | import java.util.*;
13 | import java.util.stream.Collectors;
14 |
15 | @Service
16 | public class UserService {
17 | private static final Logger logger = LoggerFactory.getLogger(UserService.class);
18 |
19 | private final Map userDB = new HashMap<>();
20 |
21 | @Autowired
22 | private QueryHistoryService historyService;
23 |
24 | @CachePut(cacheNames = "user", key = "#id", condition = "#saveCache")
25 | public UserPO createUser(String id, String name, boolean saveCache) {
26 | var user = UserPO.of(id, name);
27 | userDB.put(user.getId(), user);
28 | return user;
29 | }
30 |
31 | @CachePut(cacheNames = "user", key = "#user.id")
32 | public UserPO updateUser(UserPO user) {
33 | userDB.put(user.getId(), user);
34 | return user;
35 | }
36 |
37 | @Cacheable(cacheNames = "user", key = "#p0", unless = "#result.id.startsWith('test-')")
38 | public UserPO getUser(String id) {
39 | logNotReadFromCache("user", id);
40 | return userDB.get(id);
41 | }
42 |
43 | public Map getUserIdToNameMap(Collection ids) {
44 | // In real project, you may have something like "UserRepository.findByIdIn(ids)". It just needs 1 DB operation.
45 | return ids.stream()
46 | .map(userDB::get)
47 | .filter(Objects::nonNull)
48 | .collect(Collectors.toMap(UserPO::getId, UserPO::getName));
49 | }
50 |
51 | public void deleteAll() {
52 | userDB.clear();
53 | }
54 |
55 | private void logNotReadFromCache(String type, String identifier) {
56 | logger.info("Not read data from cache: {}-{}", type, identifier);
57 | historyService.add(type, identifier);
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | spring.redis.host=localhost
2 | spring.redis.port=6379
3 | spring.redis.password=
4 | spring.redis.database=0
--------------------------------------------------------------------------------
/src/test/java/com/vincent/demo/CacheTests.java:
--------------------------------------------------------------------------------
1 | package com.vincent.demo;
2 |
3 | import com.vincent.demo.log.QueryHistoryService;
4 | import com.vincent.demo.model.UserPO;
5 | import com.vincent.demo.service.LikeService;
6 | import com.vincent.demo.service.PostService;
7 | import com.vincent.demo.service.UserService;
8 | import org.junit.Before;
9 | import org.junit.Test;
10 | import org.junit.runner.RunWith;
11 | import org.springframework.beans.factory.annotation.Autowired;
12 | import org.springframework.boot.test.context.SpringBootTest;
13 | import org.springframework.cache.Cache;
14 | import org.springframework.cache.CacheManager;
15 | import org.springframework.test.context.junit4.SpringRunner;
16 |
17 | import java.util.List;
18 | import java.util.Optional;
19 | import java.util.stream.Stream;
20 |
21 | import static org.junit.Assert.*;
22 |
23 | @RunWith(SpringRunner.class)
24 | @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
25 | public class CacheTests {
26 | @Autowired
27 | private UserService userService;
28 |
29 | @Autowired
30 | private LikeService likeService;
31 |
32 | @Autowired
33 | private PostService postService;
34 |
35 | @Autowired
36 | private QueryHistoryService historyService;
37 |
38 | @Autowired
39 | private CacheManager cacheManager;
40 |
41 | @Before
42 | public void clearData() {
43 | userService.deleteAll();
44 | likeService.deleteAll();
45 | postService.deleteAll();
46 | historyService.deleteAll();
47 | Stream.of("user", "likeUserNames", "likeCount", "post").forEach(cacheName ->
48 | Optional.ofNullable(cacheManager.getCache(cacheName)).ifPresent(Cache::clear));
49 | }
50 |
51 | @Test
52 | public void testCreateUserThenCache() {
53 | var createdUser = userService.createUser("U1", "Vincent", true);
54 | var resultUser = userService.getUser(createdUser.getId());
55 |
56 | assertEquals(createdUser.getId(), resultUser.getId());
57 | assertEquals(createdUser.getName(), resultUser.getName());
58 | assertEquals(createdUser.getCreateTime(), resultUser.getCreateTime());
59 | assertFalse(historyService.contains("user", createdUser.getId()));
60 | }
61 |
62 | @Test
63 | public void testCreateUserWithoutCache() {
64 | var createdUser = userService.createUser("U1", "Vincent", false);
65 |
66 | var resultUser = userService.getUser(createdUser.getId());
67 | assertTrue(historyService.contains("user", createdUser.getId()));
68 | historyService.deleteAll();
69 |
70 | resultUser = userService.getUser(createdUser.getId());
71 | assertEquals(createdUser.getId(), resultUser.getId());
72 | assertEquals(createdUser.getName(), resultUser.getName());
73 | assertFalse(historyService.contains("user", createdUser.getId()));
74 | }
75 |
76 | @Test
77 | public void testConditionalCacheable() {
78 | var user = userService.createUser("test-U1", "Andy", false);
79 |
80 | // the prefix "test-" of id make this data always non cacheable
81 | for (var i = 0; i < 2; i++) {
82 | userService.getUser(user.getId());
83 | assertTrue(historyService.contains("user", user.getId()));
84 | historyService.deleteAll();
85 | }
86 | }
87 |
88 | @Test
89 | public void testUpdateUser() {
90 | var createdUser = userService.createUser("U1", "Vincent", true);
91 | var updatedUser = UserPO.of(createdUser.getId(), "Vincent Zheng");
92 | userService.updateUser(updatedUser);
93 |
94 | var resultUser = userService.getUser(createdUser.getId());
95 | assertEquals(updatedUser.getId(), resultUser.getId());
96 | assertEquals(updatedUser.getName(), resultUser.getName());
97 | assertFalse(historyService.contains("user", createdUser.getId()));
98 | }
99 |
100 | @Test
101 | public void testGetPostCreatorName() {
102 | var creator = userService.createUser("U1", "Vincent", false);
103 | var postPO = postService.createPost("P1", creator.getId(), "Cache Tutorial");
104 |
105 | var postVO = postService.getPost(postPO.getId());
106 | assertEquals(creator.getName(), postVO.getCreatorName());
107 | assertTrue(historyService.contains("user", creator.getId()));
108 | historyService.deleteAll();
109 |
110 | postVO = postService.getPost(postPO.getId());
111 | assertEquals(creator.getName(), postVO.getCreatorName());
112 | assertFalse(historyService.contains("user", creator.getId()));
113 | }
114 |
115 | @Test
116 | public void testGetPostLikeUserNames() {
117 | var creatorUser = userService.createUser("U1", "Vincent", false);
118 | var postPO = postService.createPost("P1", creatorUser.getId(), "Post_1");
119 |
120 | // create first like
121 | var likeUser1 = userService.createUser("U2", "Ivy", false);
122 | likeService.createLike(likeUser1.getId(), postPO.getId());
123 |
124 | var postVO = postService.getPost(postPO.getId());
125 | assertEquals(1, postVO.getLikerNames().size());
126 | assertTrue(postVO.getLikerNames().contains(likeUser1.getName()));
127 | assertTrue(historyService.contains("likeUserNames", postPO.getId()));
128 | historyService.deleteAll();
129 |
130 | postService.getPost(postPO.getId());
131 | assertFalse(historyService.contains("likeUserNames", postPO.getId()));
132 | assertFalse(historyService.contains("user", likeUser1.getId()));
133 |
134 | // create second like
135 | var likeUser2 = userService.createUser("U3", "Dora", false);
136 | likeService.createLike(likeUser2.getId(), postPO.getId());
137 |
138 | postVO = postService.getPost(postPO.getId());
139 | assertEquals(2, postVO.getLikerNames().size());
140 | assertTrue(postVO.getLikerNames().containsAll(
141 | List.of(likeUser1.getName(), likeUser2.getName())));
142 | assertTrue(historyService.contains("likeUserNames", postPO.getId()));
143 | }
144 |
145 | @Test
146 | public void testGetMostLikedPosts() {
147 | var creatorUser1 = userService.createUser("U1", "Vincent", true);
148 | var creatorUser2 = userService.createUser("U2", "Ivy", true);
149 | var creatorUser3 = userService.createUser("U3", "Dora", true);
150 |
151 | var postPO1 = postService.createPost("P1", creatorUser1.getId(), "Title_1");
152 | var postPO2 = postService.createPost("P2", creatorUser2.getId(), "Title_2");
153 | var postPO3 = postService.createPost("P3", creatorUser3.getId(), "Title_3");
154 |
155 | likeService.createLike(creatorUser1.getId(), postPO1.getId());
156 | likeService.createLike(creatorUser2.getId(), postPO1.getId());
157 | likeService.createLike(creatorUser3.getId(), postPO1.getId());
158 | likeService.createLike(creatorUser2.getId(), postPO2.getId());
159 | likeService.createLike(creatorUser3.getId(), postPO2.getId());
160 | likeService.createLike(creatorUser3.getId(), postPO3.getId());
161 |
162 | var postVOs = postService.getMostLikedPosts();
163 | assertEquals(3, postVOs.size());
164 | assertEquals(postPO1.getId(), postVOs.get(0).getId());
165 | assertEquals(postPO2.getId(), postVOs.get(1).getId());
166 | assertEquals(postPO3.getId(), postVOs.get(2).getId());
167 | assertTrue(historyService.contains("post", "mostLikedPosts"));
168 | historyService.deleteAll();
169 |
170 | postVOs = postService.getMostLikedPosts();
171 | assertEquals(3, postVOs.size());
172 | assertEquals(postPO1.getId(), postVOs.get(0).getId());
173 | assertEquals(postPO2.getId(), postVOs.get(1).getId());
174 | assertEquals(postPO3.getId(), postVOs.get(2).getId());
175 | assertFalse(historyService.contains("post", "mostLikedPosts"));
176 | }
177 | }
--------------------------------------------------------------------------------
/src/test/resources/application.properties:
--------------------------------------------------------------------------------
1 | spring.redis.host=localhost
2 | spring.redis.port=6379
3 | spring.redis.password=
4 | spring.redis.database=0
--------------------------------------------------------------------------------