@@ -29,100 +29,80 @@ public void setUp() {
2929 }
3030
3131 /**
32- * 测试 WxCpServiceApacheHttpClientImpl 的 getMsgAuditAccessToken 方法
32+ * 测试会话存档access token的缓存机制
33+ * 验证当token未过期时,直接从配置中返回缓存的token
3334 */
3435 @ Test
35- public void testGetMsgAuditAccessToken_ApacheHttpClient () throws WxErrorException {
36- // 创建一个模拟实现,不实际调用HTTP请求
37- WxCpServiceApacheHttpClientImpl service = new WxCpServiceApacheHttpClientImpl () {
38- @ Override
39- public String getMsgAuditAccessToken (boolean forceRefresh ) throws WxErrorException {
40- // 验证配置是否正确使用
41- WxCpConfigStorage storage = getWxCpConfigStorage ();
42- assertThat (storage .getMsgAuditSecret ()).isEqualTo ("testMsgAuditSecret" );
43-
44- // 模拟返回 token
45- return "mock_msg_audit_access_token" ;
46- }
47- };
48- service .setWxCpConfigStorage (config );
49-
36+ public void testGetMsgAuditAccessToken_Cache () throws WxErrorException {
37+ // 预先设置一个有效的token
38+ config .updateMsgAuditAccessToken ("cached_token" , 7200 );
39+
40+ BaseWxCpServiceImpl service = createTestService (config );
41+
42+ // 不强制刷新时应该返回缓存的token
5043 String token = service .getMsgAuditAccessToken (false );
51- assertThat (token ).isEqualTo ("mock_msg_audit_access_token " );
44+ assertThat (token ).isEqualTo ("cached_token " );
5245 }
5346
5447 /**
55- * 测试 WxCpServiceHttpComponentsImpl 的 getMsgAuditAccessToken 方法
48+ * 测试强制刷新会话存档access token
49+ * 验证forceRefresh=true时会重新获取token
5650 */
5751 @ Test
58- public void testGetMsgAuditAccessToken_HttpComponents () throws WxErrorException {
59- // 创建一个模拟实现,不实际调用HTTP请求
60- WxCpServiceHttpComponentsImpl service = new WxCpServiceHttpComponentsImpl () {
61- @ Override
62- public String getMsgAuditAccessToken (boolean forceRefresh ) throws WxErrorException {
63- // 验证配置是否正确使用
64- WxCpConfigStorage storage = getWxCpConfigStorage ();
65- assertThat (storage .getMsgAuditSecret ()).isEqualTo ("testMsgAuditSecret" );
66-
67- // 模拟返回 token
68- return "mock_msg_audit_access_token" ;
69- }
70- };
71- service .setWxCpConfigStorage (config );
72-
73- String token = service .getMsgAuditAccessToken (false );
74- assertThat (token ).isEqualTo ("mock_msg_audit_access_token" );
52+ public void testGetMsgAuditAccessToken_ForceRefresh () throws WxErrorException {
53+ // 预先设置一个有效的token
54+ config .updateMsgAuditAccessToken ("old_token" , 7200 );
55+
56+ BaseWxCpServiceImpl service = createTestServiceWithMockToken (config , "new_token" );
57+
58+ // 强制刷新应该获取新token
59+ String token = service .getMsgAuditAccessToken (true );
60+ assertThat (token ).isEqualTo ("new_token" );
7561 }
7662
7763 /**
78- * 测试 WxCpServiceOkHttpImpl 的 getMsgAuditAccessToken 方法
64+ * 测试token过期时自动刷新
65+ * 验证当token已过期时,会自动重新获取
7966 */
8067 @ Test
81- public void testGetMsgAuditAccessToken_OkHttp () throws WxErrorException {
82- // 创建一个模拟实现,不实际调用HTTP请求
83- WxCpServiceOkHttpImpl service = new WxCpServiceOkHttpImpl () {
84- @ Override
85- public String getMsgAuditAccessToken (boolean forceRefresh ) throws WxErrorException {
86- // 验证配置是否正确使用
87- WxCpConfigStorage storage = getWxCpConfigStorage ();
88- assertThat (storage .getMsgAuditSecret ()).isEqualTo ("testMsgAuditSecret" );
89-
90- // 模拟返回 token
91- return "mock_msg_audit_access_token" ;
92- }
93- };
94- service .setWxCpConfigStorage (config );
95-
68+ public void testGetMsgAuditAccessToken_Expired () throws WxErrorException {
69+ // 设置一个已过期的token(过期时间为0)
70+ config .updateMsgAuditAccessToken ("expired_token" , 0 );
71+ // 等待一下确保过期
72+ try {
73+ Thread .sleep (100 );
74+ } catch (InterruptedException e ) {
75+ Thread .currentThread ().interrupt ();
76+ }
77+
78+ BaseWxCpServiceImpl service = createTestServiceWithMockToken (config , "refreshed_token" );
79+
80+ // 过期的token应该被自动刷新
9681 String token = service .getMsgAuditAccessToken (false );
97- assertThat (token ).isEqualTo ("mock_msg_audit_access_token " );
82+ assertThat (token ).isEqualTo ("refreshed_token " );
9883 }
9984
10085 /**
101- * 测试 WxCpServiceJoddHttpImpl 的 getMsgAuditAccessToken 方法
86+ * 测试获取锁机制
87+ * 验证配置中的锁可以正常获取和使用
10288 */
10389 @ Test
104- public void testGetMsgAuditAccessToken_JoddHttp () throws WxErrorException {
105- // 创建一个模拟实现,不实际调用HTTP请求
106- WxCpServiceJoddHttpImpl service = new WxCpServiceJoddHttpImpl () {
107- @ Override
108- public String getMsgAuditAccessToken (boolean forceRefresh ) throws WxErrorException {
109- // 验证配置是否正确使用
110- WxCpConfigStorage storage = getWxCpConfigStorage ();
111- assertThat (storage .getMsgAuditSecret ()).isEqualTo ("testMsgAuditSecret" );
112-
113- // 模拟返回 token
114- return "mock_msg_audit_access_token" ;
115- }
116- };
117- service .setWxCpConfigStorage (config );
118-
119- String token = service .getMsgAuditAccessToken (false );
120- assertThat (token ).isEqualTo ("mock_msg_audit_access_token" );
90+ public void testGetMsgAuditAccessToken_Lock () {
91+ // 验证配置提供的锁不为null
92+ assertThat (config .getMsgAuditAccessTokenLock ()).isNotNull ();
93+
94+ // 验证锁可以正常使用
95+ config .getMsgAuditAccessTokenLock ().lock ();
96+ try {
97+ assertThat (config .getMsgAuditAccessToken ()).isNull ();
98+ } finally {
99+ config .getMsgAuditAccessTokenLock ().unlock ();
100+ }
121101 }
122102
123103 /**
124104 * 创建一个用于测试的BaseWxCpServiceImpl实现,
125- * 模拟在msgAuditSecret未配置时抛出异常的行为
105+ * 用于测试缓存和过期逻辑
126106 */
127107 private BaseWxCpServiceImpl createTestService (WxCpConfigStorage config ) {
128108 return new BaseWxCpServiceImpl () {
@@ -148,12 +128,81 @@ public String getAccessToken(boolean forceRefresh) throws WxErrorException {
148128
149129 @ Override
150130 public String getMsgAuditAccessToken (boolean forceRefresh ) throws WxErrorException {
131+ // 检查是否需要刷新
132+ if (!getWxCpConfigStorage ().isMsgAuditAccessTokenExpired () && !forceRefresh ) {
133+ return getWxCpConfigStorage ().getMsgAuditAccessToken ();
134+ }
135+
151136 // 使用会话存档secret获取access_token
152137 String msgAuditSecret = getWxCpConfigStorage ().getMsgAuditSecret ();
153138 if (msgAuditSecret == null || msgAuditSecret .trim ().isEmpty ()) {
154139 throw new WxErrorException ("会话存档secret未配置" );
155140 }
156- return "mock_token" ;
141+
142+ // 模拟HTTP请求失败,实际测试中应该返回缓存的token
143+ return getWxCpConfigStorage ().getMsgAuditAccessToken ();
144+ }
145+
146+ @ Override
147+ public void initHttp () {
148+ }
149+
150+ @ Override
151+ public WxCpConfigStorage getWxCpConfigStorage () {
152+ return config ;
153+ }
154+ };
155+ }
156+
157+ /**
158+ * 创建一个用于测试的BaseWxCpServiceImpl实现,
159+ * 模拟返回指定的token(用于测试刷新逻辑)
160+ */
161+ private BaseWxCpServiceImpl createTestServiceWithMockToken (WxCpConfigStorage config , String mockToken ) {
162+ return new BaseWxCpServiceImpl () {
163+ @ Override
164+ public Object getRequestHttpClient () {
165+ return null ;
166+ }
167+
168+ @ Override
169+ public Object getRequestHttpProxy () {
170+ return null ;
171+ }
172+
173+ @ Override
174+ public HttpClientType getRequestType () {
175+ return null ;
176+ }
177+
178+ @ Override
179+ public String getAccessToken (boolean forceRefresh ) throws WxErrorException {
180+ return "test_access_token" ;
181+ }
182+
183+ @ Override
184+ public String getMsgAuditAccessToken (boolean forceRefresh ) throws WxErrorException {
185+ // 使用锁机制
186+ var lock = getWxCpConfigStorage ().getMsgAuditAccessTokenLock ();
187+ lock .lock ();
188+ try {
189+ // 检查是否需要刷新
190+ if (!getWxCpConfigStorage ().isMsgAuditAccessTokenExpired () && !forceRefresh ) {
191+ return getWxCpConfigStorage ().getMsgAuditAccessToken ();
192+ }
193+
194+ // 使用会话存档secret获取access_token
195+ String msgAuditSecret = getWxCpConfigStorage ().getMsgAuditSecret ();
196+ if (msgAuditSecret == null || msgAuditSecret .trim ().isEmpty ()) {
197+ throw new WxErrorException ("会话存档secret未配置" );
198+ }
199+
200+ // 模拟获取新token并更新配置
201+ getWxCpConfigStorage ().updateMsgAuditAccessToken (mockToken , 7200 );
202+ return mockToken ;
203+ } finally {
204+ lock .unlock ();
205+ }
157206 }
158207
159208 @ Override
0 commit comments