1
0
mirror of synced 2026-10-25 01:16:13 +08:00

: white_check_mark: 启用离线测试门禁并修复解析与测试配置问题

This commit is contained in:
Binary Wang
2026-09-13 12:06:07 +08:00
parent f95fd76b05
commit 1bcb7b3873
33 changed files with 346 additions and 197 deletions

View File

@@ -127,21 +127,37 @@
<suiteXmlFiles>
<suiteXmlFile>src/test/resources/testng.xml</suiteXmlFile>
</suiteXmlFiles>
<argLine>
--add-opens java.base/java.lang=ALL-UNNAMED
--add-opens java.base/java.lang.reflect=ALL-UNNAMED
--add-opens java.base/java.io=ALL-UNNAMED
--add-opens java.base/java.security=ALL-UNNAMED
--add-opens java.base/java.util=ALL-UNNAMED
--add-opens java.management/javax.management=ALL-UNNAMED
--add-opens java.naming/javax.naming=ALL-UNNAMED
</argLine>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>test-jdk9-opens</id>
<activation>
<jdk>[9,)</jdk>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>
--add-opens java.base/java.lang=ALL-UNNAMED
--add-opens java.base/java.lang.reflect=ALL-UNNAMED
--add-opens java.base/java.io=ALL-UNNAMED
--add-opens java.base/java.security=ALL-UNNAMED
--add-opens java.base/java.util=ALL-UNNAMED
--add-opens java.management/javax.management=ALL-UNNAMED
--add-opens java.naming/javax.naming=ALL-UNNAMED
</argLine>
</configuration>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>native-image</id>
<activation>

View File

@@ -545,8 +545,12 @@ public class WxCpMessage implements Serializable {
articleJson.addProperty("description", article.getDescription());
articleJson.addProperty("url", article.getUrl());
articleJson.addProperty("picurl", article.getPicUrl());
articleJson.addProperty("appid", article.getAppid());
articleJson.addProperty("pagepath", article.getPagepath());
if (StringUtils.isNotBlank(article.getAppid())) {
articleJson.addProperty("appid", article.getAppid());
}
if (StringUtils.isNotBlank(article.getPagepath())) {
articleJson.addProperty("pagepath", article.getPagepath());
}
articleJsonArray.add(articleJson);
}
newsJsonObject.add("articles", articleJsonArray);
@@ -619,7 +623,9 @@ public class WxCpMessage implements Serializable {
if (StringUtils.isNotBlank(this.getSourceDesc())) {
source.addProperty("desc", this.getSourceDesc());
}
source.addProperty("desc_color", this.getSourceDescColor());
if (this.getSourceDescColor() != null) {
source.addProperty("desc_color", this.getSourceDescColor());
}
template.add("source", source);
}

View File

@@ -59,7 +59,9 @@ public class TemplateCardButton implements Serializable {
btnObject.addProperty("style", this.getStyle());
}
btnObject.addProperty("key", this.getKey());
btnObject.addProperty("type", this.getType());
if (this.getType() != 0) {
btnObject.addProperty("type", this.getType());
}
if (null != this.getUrl()) {
btnObject.addProperty("url", this.getUrl());
}

View File

@@ -1,6 +1,6 @@
package me.chanjar.weixin.cp.api;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxError;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.error.WxRuntimeException;
import me.chanjar.weixin.common.util.http.RequestExecutor;
@@ -12,76 +12,66 @@ import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicInteger;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.expectThrows;
/**
* The type Wx cp busy retry test.
* 企业微信系统繁忙重试测试。
*/
@Test
@Slf4j
public class WxCpBusyRetryTest {
/**
* Get service object [ ] [ ].
*
* @return the object [ ] [ ]
*/
@DataProvider(name = "getService")
public Object[][] getService() {
WxCpService service = new WxCpServiceImpl() {
@Override
public synchronized <T, E> T executeInternal(
RequestExecutor<T, E> executor, String uri, E data, boolean doNotAutoRefresh)
throws WxErrorException {
log.info("Executed");
throw new WxErrorException("something");
}
};
BusyService service = new BusyService();
service.setMaxRetryTimes(3);
service.setRetrySleepMillis(500);
return new Object[][]{
new Object[]{service}
};
service.setRetrySleepMillis(1);
return new Object[][]{{service}};
}
/**
* Test retry.
*
* @param service the service
* @throws WxErrorException the wx error exception
*/
@Test(dataProvider = "getService", expectedExceptions = RuntimeException.class)
public void testRetry(WxCpService service) throws WxErrorException {
service.execute(null, null, null);
}
/**
* Test retry in thread pool.
*
* @param service the service
* @throws InterruptedException the interrupted exception
* @throws ExecutionException the execution exception
* @param service 始终返回系统繁忙错误的服务
*/
@Test(dataProvider = "getService")
public void testRetryInThreadPool(final WxCpService service) throws InterruptedException, ExecutionException {
// 当线程池中的线程复用的时候,还是能保证相同的重试次数
ExecutorService executorService = Executors.newFixedThreadPool(1);
Runnable runnable = () -> {
try {
System.out.println("=====================");
System.out.println(Thread.currentThread().getName() + ": testRetry");
service.execute(null, null, null);
} catch (WxErrorException e) {
throw new WxRuntimeException(e);
} catch (RuntimeException e) {
// OK
}
};
Future<?> submit1 = executorService.submit(runnable);
Future<?> submit2 = executorService.submit(runnable);
submit1.get();
submit2.get();
public void testRetry(WxCpService service) {
assertRetryExhausted(service);
assertEquals(((BusyService) service).calls.get(), 4);
}
/**
* @param service 始终返回系统繁忙错误的服务
* @throws InterruptedException 等待任务被中断
* @throws ExecutionException 后台测试失败
*/
@Test(dataProvider = "getService")
public void testRetryInThreadPool(WxCpService service) throws InterruptedException, ExecutionException {
ExecutorService executorService = Executors.newFixedThreadPool(1);
try {
Future<?> first = executorService.submit(() -> assertRetryExhausted(service));
Future<?> second = executorService.submit(() -> assertRetryExhausted(service));
first.get();
second.get();
assertEquals(((BusyService) service).calls.get(), 8);
} finally {
executorService.shutdownNow();
}
}
private void assertRetryExhausted(WxCpService service) {
WxRuntimeException failure = expectThrows(WxRuntimeException.class,
() -> service.execute(null, (String) null, null));
assertTrue(failure.getMessage().contains("超出重试次数"));
}
private static class BusyService extends WxCpServiceImpl {
private final AtomicInteger calls = new AtomicInteger();
@Override
public synchronized <T, E> T executeInternal(RequestExecutor<T, E> executor, String uri, E data,
boolean doNotAutoRefresh) throws WxErrorException {
calls.incrementAndGet();
throw new WxErrorException(WxError.builder().errorCode(-1).errorMsg("system busy").build());
}
}
}

View File

@@ -5,6 +5,7 @@ import me.chanjar.weixin.common.session.StandardSessionManager;
import me.chanjar.weixin.common.session.WxSessionManager;
import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage;
import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage;
import me.chanjar.weixin.cp.api.impl.WxCpServiceImpl;
import me.chanjar.weixin.cp.message.WxCpMessageHandler;
import me.chanjar.weixin.cp.message.WxCpMessageMatcher;
import me.chanjar.weixin.cp.message.WxCpMessageRouter;
@@ -31,6 +32,7 @@ public class WxCpMessageRouterTest {
*/
@Test(enabled = false)
public void prepare(boolean async, StringBuffer sb, WxCpMessageRouter router) {
router.setMessageDuplicateChecker(new me.chanjar.weixin.common.api.WxMessageInMemoryDuplicateChecker());
router
.rule()
.async(async)
@@ -72,7 +74,7 @@ public class WxCpMessageRouterTest {
@Test(dataProvider = "messages-1")
public void testSync(WxCpXmlMessage message, String expected) {
StringBuffer sb = new StringBuffer();
WxCpMessageRouter router = new WxCpMessageRouter(null);
WxCpMessageRouter router = new WxCpMessageRouter(new WxCpServiceImpl());
prepare(false, sb, router);
router.route(message);
Assert.assertEquals(sb.toString(), expected);
@@ -88,7 +90,7 @@ public class WxCpMessageRouterTest {
@Test(dataProvider = "messages-1")
public void testAsync(WxCpXmlMessage message, String expected) throws InterruptedException {
StringBuffer sb = new StringBuffer();
WxCpMessageRouter router = new WxCpMessageRouter(null);
WxCpMessageRouter router = new WxCpMessageRouter(new WxCpServiceImpl());
prepare(true, sb, router);
router.route(message);
Thread.sleep(500);
@@ -101,7 +103,7 @@ public class WxCpMessageRouterTest {
* @throws InterruptedException the interrupted exception
*/
public void testConcurrency() throws InterruptedException {
final WxCpMessageRouter router = new WxCpMessageRouter(null);
final WxCpMessageRouter router = new WxCpMessageRouter(new WxCpServiceImpl());
router.rule().handler(new WxCpMessageHandler() {
@Override
public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map<String, Object> context, WxCpService wxCpService,
@@ -214,7 +216,7 @@ public class WxCpMessageRouterTest {
public void testSessionClean1(StandardSessionManager ism) throws InterruptedException {
// 两个同步请求,看是否处理完毕后会被清理掉
final WxCpMessageRouter router = new WxCpMessageRouter(null);
final WxCpMessageRouter router = new WxCpMessageRouter(new WxCpServiceImpl());
router.setSessionManager(ism);
router
.rule().async(false).handler(new WxSessionMessageHandler()).next()
@@ -240,7 +242,7 @@ public class WxCpMessageRouterTest {
// 1个同步,1个异步请求,看是否处理完毕后会被清理掉
{
final WxCpMessageRouter router = new WxCpMessageRouter(null);
final WxCpMessageRouter router = new WxCpMessageRouter(new WxCpServiceImpl());
router.setSessionManager(ism);
router
.rule().async(false).handler(new WxSessionMessageHandler()).next()
@@ -254,7 +256,7 @@ public class WxCpMessageRouterTest {
Assert.assertEquals(ism.getActiveSessions(), 0);
}
{
final WxCpMessageRouter router = new WxCpMessageRouter(null);
final WxCpMessageRouter router = new WxCpMessageRouter(new WxCpServiceImpl());
router.setSessionManager(ism);
router
.rule().async(true).handler(new WxSessionMessageHandler()).next()
@@ -280,7 +282,7 @@ public class WxCpMessageRouterTest {
public void testSessionClean3(StandardSessionManager ism) throws InterruptedException {
// 2个异步请求,看是否处理完毕后会被清理掉
final WxCpMessageRouter router = new WxCpMessageRouter(null);
final WxCpMessageRouter router = new WxCpMessageRouter(new WxCpServiceImpl());
router.setSessionManager(ism);
router
.rule().async(true).handler(new WxSessionMessageHandler()).next()
@@ -306,7 +308,7 @@ public class WxCpMessageRouterTest {
// 一个同步请求,看是否处理完毕后会被清理掉
{
final WxCpMessageRouter router = new WxCpMessageRouter(null);
final WxCpMessageRouter router = new WxCpMessageRouter(new WxCpServiceImpl());
router.setSessionManager(ism);
router
.rule().async(false).handler(new WxSessionMessageHandler()).end();
@@ -320,7 +322,7 @@ public class WxCpMessageRouterTest {
}
{
final WxCpMessageRouter router = new WxCpMessageRouter(null);
final WxCpMessageRouter router = new WxCpMessageRouter(new WxCpServiceImpl());
router.setSessionManager(ism);
router
.rule().async(true).handler(new WxSessionMessageHandler()).end();

View File

@@ -124,7 +124,7 @@ public class WxCpXmlMessageTest {
assertEquals(wxMessage.getFromUserName(), "xiaohe");
assertEquals(wxMessage.getCreateTime(), Long.valueOf(1502012364L));
assertEquals(wxMessage.getMsgType(), WxConsts.XmlMsgType.EVENT);
assertEquals(wxMessage.getAgentId(), Integer.valueOf(1000004));
assertEquals(wxMessage.getAgentId(), "1000004");
assertEquals(wxMessage.getEvent(), "pic_weixin");
assertEquals(wxMessage.getEventKey(), "faceSimilarity");
assertNotNull(wxMessage.getSendPicsInfo());
@@ -190,7 +190,7 @@ public class WxCpXmlMessageTest {
assertEquals(wxMessage.getFromUserName(), "FromUser");
assertEquals(wxMessage.getCreateTime(), Long.valueOf(123456789L));
assertEquals(wxMessage.getMsgType(), WxConsts.XmlMsgType.EVENT);
assertEquals(wxMessage.getAgentId(), Integer.valueOf(1));
assertEquals(wxMessage.getAgentId(), "1");
assertEquals(wxMessage.getEvent(), TASKCARD_CLICK);
assertEquals(wxMessage.getEventKey(), "key111");
assertEquals(wxMessage.getTaskId(), "taskid111");

View File

@@ -86,7 +86,7 @@ public class WxCpTpTagServiceImplTest {
String url = configStorage.getApiUrl(TAG_LIST);
String result = "{\"errcode\":0,\"errmsg\":\"ok\",\"taglist\":[{\"tagid\":1,\"tagname\":\"a\"},{\"tagid\":2," +
"\"tagname\":\"b\"}]}";
when(wxCpTpService.get(eq(url), anyString())).thenReturn(result);
when(wxCpTpService.get(eq(url), isNull())).thenReturn(result);
List<WxCpTpTag> wxCpTpTags = wxCpTpTagService.listAll();
assertNotNull(wxCpTpTags);
@@ -106,7 +106,7 @@ public class WxCpTpTagServiceImplTest {
String url = String.format(configStorage.getApiUrl(TAG_GET), tagId);
String result = "{\"errcode\":0,\"errmsg\":\"ok\",\"tagname\":\"乒乓球协会\",\"userlist\":[{\"userid\":\"zhangsan\"," +
"\"name\":\"李四\"}],\"partylist\":[2]}";
when(wxCpTpService.get(eq(url), anyString())).thenReturn(result);
when(wxCpTpService.get(eq(url), isNull())).thenReturn(result);
WxCpTpTagGetResult getResult = wxCpTpTagService.get(tagId);
assertEquals(getResult.getTagname(), "乒乓球协会");

View File

@@ -4,14 +4,11 @@
<test name="API_Test">
<classes>
<class name="me.chanjar.weixin.cp.api.WxCpBusyRetryTest"/>
<class name="me.chanjar.weixin.cp.api.WxCpBaseAPITest"/>
<class name="me.chanjar.weixin.cp.api.WxCpMessageRouterTest"/>
<class name="me.chanjar.weixin.cp.tp.service.impl.WxCpTpServiceApacheHttpClientImplTest"/>
<class name="me.chanjar.weixin.cp.config.impl.WxCpTpDefaultConfigImplTest"/>
<class name="me.chanjar.weixin.cp.config.impl.WxCpDefaultConfigImplMsgAuditSdkTest"/>
<class name="me.chanjar.weixin.cp.tp.service.impl.WxCpTpTagServiceImplTest"/>
<class name="me.chanjar.weixin.cp.tp.service.impl.WxCpTpMessageServiceImplTest"/>
<class name="me.chanjar.weixin.cp.api.impl.WxCpHrServiceImplTest"/>
<class name="me.chanjar.weixin.cp.api.impl.BaseWxCpServiceImplLogTest"/>
<class name="me.chanjar.weixin.cp.api.impl.WxCpIntelligentRobotApiModeServiceTest"/>
</classes>
@@ -26,7 +23,6 @@
<class name="me.chanjar.weixin.cp.bean.message.WxCpXmlOutVideoMessageTest"/>
<class name="me.chanjar.weixin.cp.bean.message.WxCpXmlOutVoiceMessageTest"/>
<class name="me.chanjar.weixin.cp.bean.message.WxCpXmlOutTextMessageTest"/>
<class name="me.chanjar.weixin.cp.bean.todo.WxCpTodoServiceMockTest"/>
<class name="me.chanjar.weixin.cp.util.crypto.WxCpIntelligentRobotCryptUtilTest"/>
<class name="me.chanjar.weixin.cp.bean.kf.WxCpKfKnowledgeTest"/>
</classes>