mirror of
https://gitee.com/binary/weixin-java-tools.git
synced 2025-09-23 04:23:51 +08:00
修改javadoc, readme, 单元测试代码
This commit is contained in:
263
README.md
263
README.md
@@ -1,11 +1,11 @@
|
|||||||
weixin-tools
|
weixin-java-tools
|
||||||
===========
|
===========
|
||||||
|
|
||||||
微信java开发工具,本项目提供了两个主要特性:微信消息路由器、微信Java API
|
微信java开发工具,本项目提供了两个主要特性:微信消息路由器、微信Java API
|
||||||
|
|
||||||
## 微信消息路由器
|
## 微信消息路由器
|
||||||
|
|
||||||
你可以使用``WxMessageRouter``来对微信推送过来的消息、事件进行路由,交给特定的``WxMessageHandler``处理。
|
你可以使用``WxMessageRouter``来对微信推送过来的消息、事件进行路由,交给的``WxMessageHandler``处理。
|
||||||
|
|
||||||
使用方法:
|
使用方法:
|
||||||
|
|
||||||
@@ -13,32 +13,269 @@ weixin-tools
|
|||||||
WxMessageRouter router = new WxMessageRouter();
|
WxMessageRouter router = new WxMessageRouter();
|
||||||
router
|
router
|
||||||
.rule()
|
.rule()
|
||||||
.msgType("MSG_TYPE").event("EVENT").eventKey("EVENT_KEY").content("CONTENT")
|
.msgType("MSG_TYPE")
|
||||||
.interceptor(interceptor, ...).handler(handler, ...)
|
.event("EVENT")
|
||||||
|
.eventKey("EVENT_KEY")
|
||||||
|
.content("CONTENT")
|
||||||
|
.interceptor(interceptor).handler(handler)
|
||||||
.end()
|
.end()
|
||||||
.rule()
|
.rule()
|
||||||
// 另外一个匹配规则
|
.msgType("MSG_TYPE")
|
||||||
|
.handler(handler)
|
||||||
.end()
|
.end()
|
||||||
;
|
;
|
||||||
|
|
||||||
// 将WxXmlMessage交给消息路由器
|
// 将WxXmlMessage交给消息路由器
|
||||||
|
WxXmlMessage message = WxXmlMessage.fromXml(xml);
|
||||||
router.route(message);
|
router.route(message);
|
||||||
```
|
```
|
||||||
|
|
||||||
1. 开发人员需实现自己的``WxMessageHandler``和``WxMessageInterceptor``
|
1. 开发人员需实现自己的``WxMessageHandler``和``WxMessageInterceptor``
|
||||||
1. 配置路由规则时要按照从细到粗的原则,否则可能消息可能会被提前处理
|
1. 配置路由规则时要按照从细到粗的原则,否则可能消息可能会被提前处理
|
||||||
2. 默认情况下消息只会被处理一次,除非使用 ``WxMessageRouter#Rule#next()``
|
2. 默认情况下消息只会被处理一次,除非使用 ``Rule.next()``
|
||||||
3. 规则的结束必须用``WxMessageRouter#Rule#end()``或者``WxMessageRouter#Rule#next()``,否则不会生效
|
3. 规则的结束必须用``Rule.end()``或者``Rule.next()``,否则不会生效
|
||||||
|
4. 具体使用可以看源代码中的``WxMessageRouterTest``单元测试,或者查看Javadoc
|
||||||
|
|
||||||
## 微信Java API
|
## 微信Java API
|
||||||
|
|
||||||
使用``WxService``可以调用微信API。目前实现了以下功能,其余功能以后陆续补充:
|
使用``WxService``可以调用微信API。目前实现的功能有:
|
||||||
|
|
||||||
1. 发送客服消息
|
### 构造WxService
|
||||||
1. 创建自定义菜单
|
|
||||||
1. 删除自定义菜单
|
``WxService``依赖于``WxConfigStorage``,``WxConfigStorage``是微信客户端配置所存储的地方,本工具提供了默认的``WxInMemoryConfigStorage``,这是一个存储在内存中的实现,生产环境中需要开发人员提供自己的实现。
|
||||||
1. 查询自定义菜单
|
|
||||||
1. 刷新access_token
|
```java
|
||||||
|
WxConfigStorage config = new WxInMemoryConfigStorage();
|
||||||
|
config.setAppId(...);
|
||||||
|
config.setSecret(...);
|
||||||
|
config.setToken(...);
|
||||||
|
WxServiceImpl wxService = new WxServiceImpl();
|
||||||
|
wxService.setWxConfigStorage(config);
|
||||||
|
```
|
||||||
|
|
||||||
|
### 验证消息
|
||||||
|
|
||||||
|
```java
|
||||||
|
if(!wxService.checkSignature(timestamp, nonce, signature)) {
|
||||||
|
// 验证失败
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 刷新access_token
|
||||||
|
|
||||||
|
```java
|
||||||
|
wxService.accessTokenRefresh();
|
||||||
|
```
|
||||||
|
|
||||||
|
刷新后的accessToken存在WxConfigStorage中。
|
||||||
|
|
||||||
|
### 多媒体文件
|
||||||
|
|
||||||
|
#### 上传多媒体文件
|
||||||
|
```java
|
||||||
|
InputStream inputStream = ...;
|
||||||
|
File file = ...;
|
||||||
|
WxMediaUploadResult res = wxService.mediaUpload(mediaType, fileType, inputStream);
|
||||||
|
// 或者
|
||||||
|
res = wxService.mediaUpload(mediaType, file);
|
||||||
|
res.getType();
|
||||||
|
res.getCreated_at();
|
||||||
|
res.getMedia_id();
|
||||||
|
res.getThumb_media_id();
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 下载多媒体文件
|
||||||
|
```java
|
||||||
|
// 获得一个在系统临时目录的一个文件
|
||||||
|
File file = wxService.mediaDownload(media_id);
|
||||||
|
```
|
||||||
|
|
||||||
|
### 分组管理
|
||||||
|
|
||||||
|
#### 创建分组
|
||||||
|
```java
|
||||||
|
WxGroup res = wxService.groupCreate("测试分组1");
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 获得分组列表
|
||||||
|
```java
|
||||||
|
List<WxGroup> groupList = wxService.groupGet();
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 更新分组名
|
||||||
|
```java
|
||||||
|
WxGroup g = new WxGroup();
|
||||||
|
g.setId(...);
|
||||||
|
g.setName(...);
|
||||||
|
wxService.groupUpdate(group);
|
||||||
|
```
|
||||||
|
|
||||||
|
### 用户管理
|
||||||
|
|
||||||
|
#### 更新用户备注名
|
||||||
|
```java
|
||||||
|
wxService.userUpdateRemark(openid, "测试备注名");
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 获得用户信息
|
||||||
|
```java
|
||||||
|
String lang = "zh_CN"; //语言
|
||||||
|
WxUser user = wxService.userInfo(openid, lang);
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 获得用户列表
|
||||||
|
```java
|
||||||
|
WxUserList wxUserList = wxService.userList(next_openid);
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 查询用户所在分组
|
||||||
|
```java
|
||||||
|
long groupid = wxService.userGetGroup(openid);
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 将用户移到分组
|
||||||
|
```java
|
||||||
|
wxService.userUpdateGroup(openid, to_groupid);
|
||||||
|
```
|
||||||
|
|
||||||
|
### 发送客服消息
|
||||||
|
|
||||||
|
```java
|
||||||
|
WxCustomMessage message = new WxCustomMessage();
|
||||||
|
// 设置消息的内容等信息
|
||||||
|
wxService.customMessageSend(message);
|
||||||
|
```
|
||||||
|
|
||||||
|
### 群发消息
|
||||||
|
|
||||||
|
下面用用户列表群发(``WxMassOpenIdsMessage``)做例子,如果要使用分组群发,则使用``WxMassGroupMessage``即可。
|
||||||
|
|
||||||
|
#### 文本消息
|
||||||
|
```java
|
||||||
|
WxMassOpenIdsMessage massMessage = new WxMassOpenIdsMessage();
|
||||||
|
massMessage.setMsgtype(WxConsts.MASS_MSG_TEXT);
|
||||||
|
massMessage.setContent("消息内容");
|
||||||
|
massMessage.getTouser().add(openid);
|
||||||
|
|
||||||
|
WxMassSendResult massResult = wxService.massOpenIdsMessageSend(massMessage);
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 视频消息
|
||||||
|
```java
|
||||||
|
WxMediaUploadResult uploadMediaRes = wxService.mediaUpload(WxConsts.MEDIA_VIDEO, WxConsts.FILE_MP4, inputStream);
|
||||||
|
|
||||||
|
// 把视频变成可被群发的媒体
|
||||||
|
WxMassVideo video = new WxMassVideo();
|
||||||
|
video.setTitle("测试标题");
|
||||||
|
video.setDescription("测试描述");
|
||||||
|
video.setMedia_id(uploadMediaRes.getMedia_id());
|
||||||
|
WxMassUploadResult uploadResult = wxService.massVideoUpload(video);
|
||||||
|
|
||||||
|
WxMassOpenIdsMessage massMessage = new WxMassOpenIdsMessage();
|
||||||
|
massMessage.setMsgtype(WxConsts.MASS_MSG_VIDEO);
|
||||||
|
massMessage.setMedia_id(uploadResult.getMedia_id());
|
||||||
|
massMessage.getTouser().add(openid);
|
||||||
|
|
||||||
|
WxMassSendResult massResult = wxService.massOpenIdsMessageSend(massMessage);
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 图片消息
|
||||||
|
```java
|
||||||
|
WxMediaUploadResult uploadMediaRes = wxService.mediaUpload(WxConsts.MEDIA_IMAGE, WxConsts.FILE_JPG, inputStream);
|
||||||
|
|
||||||
|
WxMassOpenIdsMessage massMessage = new WxMassOpenIdsMessage();
|
||||||
|
massMessage.setMsgtype(WxConsts.MASS_MSG_IMAGE);
|
||||||
|
massMessage.setMedia_id(uploadMediaRes.getMedia_id());
|
||||||
|
massMessage.getTouser().add(openid);
|
||||||
|
|
||||||
|
WxMassSendResult massResult = wxService.massOpenIdsMessageSend(massMessage);
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 语音消息
|
||||||
|
```java
|
||||||
|
WxMediaUploadResult uploadMediaRes = wxService.mediaUpload(WxConsts.MEDIA_VOICE, WxConsts.FILE_MP3, inputStream);
|
||||||
|
|
||||||
|
WxMassOpenIdsMessage massMessage = new WxMassOpenIdsMessage();
|
||||||
|
massMessage.setMsgtype(WxConsts.MASS_MSG_VOICE);
|
||||||
|
massMessage.setMedia_id(uploadMediaRes.getMedia_id());
|
||||||
|
massMessage.getTouser().add(openid);
|
||||||
|
|
||||||
|
WxMassSendResult massResult = wxService.massOpenIdsMessageSend(massMessage);
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 图文消息
|
||||||
|
```java
|
||||||
|
// 先上传图文消息里需要的图片
|
||||||
|
WxMediaUploadResult uploadMediaRes = wxService.mediaUpload(WxConsts.MEDIA_IMAGE, WxConsts.FILE_JPG, inputStream);
|
||||||
|
|
||||||
|
WxMassNews news = new WxMassNews();
|
||||||
|
WxMassNewsArticle article1 = new WxMassNewsArticle();
|
||||||
|
article1.setTitle("标题1");
|
||||||
|
article1.setContent("内容1");
|
||||||
|
article1.setThumb_media_id(uploadMediaRes.getMedia_id());
|
||||||
|
news.addArticle(article1);
|
||||||
|
|
||||||
|
WxMassNewsArticle article2 = new WxMassNewsArticle();
|
||||||
|
article2.setTitle("标题2");
|
||||||
|
article2.setContent("内容2");
|
||||||
|
article2.setThumb_media_id(uploadMediaRes.getMedia_id());
|
||||||
|
article2.setShow_cover_pic(true);
|
||||||
|
article2.setAuthor("作者2");
|
||||||
|
article2.setContent_source_url("www.baidu.com");
|
||||||
|
article2.setDigest("摘要2");
|
||||||
|
news.addArticle(article2);
|
||||||
|
|
||||||
|
WxMassUploadResult massUploadResult = wxService.massNewsUpload(news);
|
||||||
|
|
||||||
|
WxMassOpenIdsMessage massMessage = new WxMassOpenIdsMessage();
|
||||||
|
massMessage.setMsgtype(WxConsts.MASS_MSG_NEWS);
|
||||||
|
massMessage.setMedia_id(uploadResult.getMedia_id());
|
||||||
|
massMessage.getTouser().add(openid);
|
||||||
|
|
||||||
|
WxMassSendResult massResult = wxService.massOpenIdsMessageSend(massMessage);
|
||||||
|
```
|
||||||
|
|
||||||
|
### 自定义菜单
|
||||||
|
|
||||||
|
#### 创建自定义菜单
|
||||||
|
```java
|
||||||
|
WxMenu wxMenu = new WxMenu();
|
||||||
|
// 设置菜单
|
||||||
|
wxService.menuCreate(wxMenu);
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 删除自定义菜单
|
||||||
|
```java
|
||||||
|
wxService.menuDelete();
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 获得自定义菜单
|
||||||
|
```java
|
||||||
|
WxMenu wxMenu = wxService.menuGet()
|
||||||
|
```
|
||||||
|
|
||||||
|
### 二维码
|
||||||
|
|
||||||
|
#### 获得二维码ticket
|
||||||
|
```java
|
||||||
|
// 临时ticket
|
||||||
|
WxQrCodeTicket ticket = wxService.qrCodeCreateTmpTicket(scene, expire_seconds);
|
||||||
|
// 永久ticket
|
||||||
|
WxQrCodeTicket ticket = wxService.qrCodeCreateLastTicket(scene);
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 换取二维码图片
|
||||||
|
```java
|
||||||
|
WxQrCodeTicket ticket = ...;
|
||||||
|
// 获得一个在系统临时目录下的文件,是jpg格式的
|
||||||
|
File file = wxService.qrCodePicture(ticket);
|
||||||
|
```
|
||||||
|
|
||||||
|
### 短链接
|
||||||
|
|
||||||
|
```java
|
||||||
|
String shortUrl = wxService.shortUrl("www.baidu.com");
|
||||||
|
```
|
||||||
|
|
||||||
## 如何执行单元测试
|
## 如何执行单元测试
|
||||||
将 ``src/test/resources/test-config.sample.xml`` 改成 ``test-config.xml`` 设置appId, secret, accessToken(可选), openId
|
将 ``src/test/resources/test-config.sample.xml`` 改成 ``test-config.xml`` 设置appId, secret, accessToken(可选), openId
|
||||||
|
@@ -210,7 +210,7 @@ public interface WxService {
|
|||||||
* @param openid 微信用户的openid
|
* @param openid 微信用户的openid
|
||||||
* @throws WxErrorException
|
* @throws WxErrorException
|
||||||
*/
|
*/
|
||||||
public long groupQueryUserGroup(String openid) throws WxErrorException;
|
public long userGetGroup(String openid) throws WxErrorException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <pre>
|
* <pre>
|
||||||
@@ -296,7 +296,7 @@ public interface WxService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* <pre>
|
* <pre>
|
||||||
* 换取二维码图片
|
* 换取二维码图片文件,jpg格式
|
||||||
* 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=生成带参数的二维码
|
* 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=生成带参数的二维码
|
||||||
* </pre>
|
* </pre>
|
||||||
* @param ticket 二维码ticket
|
* @param ticket 二维码ticket
|
||||||
|
@@ -223,7 +223,7 @@ public class WxServiceImpl implements WxService {
|
|||||||
return WxGsonBuilder.INSTANCE.create().fromJson(tmpJsonElement.getAsJsonObject().get("groups"), new TypeToken<List<WxGroup>>(){}.getType());
|
return WxGsonBuilder.INSTANCE.create().fromJson(tmpJsonElement.getAsJsonObject().get("groups"), new TypeToken<List<WxGroup>>(){}.getType());
|
||||||
}
|
}
|
||||||
|
|
||||||
public long groupQueryUserGroup(String openid) throws WxErrorException {
|
public long userGetGroup(String openid) throws WxErrorException {
|
||||||
String url = "https://api.weixin.qq.com/cgi-bin/groups/getid";
|
String url = "https://api.weixin.qq.com/cgi-bin/groups/getid";
|
||||||
JsonObject o = new JsonObject();
|
JsonObject o = new JsonObject();
|
||||||
o.addProperty("openid", openid);
|
o.addProperty("openid", openid);
|
||||||
|
@@ -6,7 +6,6 @@ import org.testng.Assert;
|
|||||||
import org.testng.annotations.Guice;
|
import org.testng.annotations.Guice;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
import chanjarster.weixin.api.ApiTestModule.WxXmlConfigStorage;
|
|
||||||
import chanjarster.weixin.bean.WxGroup;
|
import chanjarster.weixin.bean.WxGroup;
|
||||||
import chanjarster.weixin.exception.WxErrorException;
|
import chanjarster.weixin.exception.WxErrorException;
|
||||||
|
|
||||||
@@ -42,22 +41,10 @@ public class WxGroupAPITest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(dependsOnMethods="testGroupCreate")
|
|
||||||
public void testGroupQueryUserGroup() throws WxErrorException {
|
|
||||||
WxXmlConfigStorage configStorage = (WxXmlConfigStorage) wxService.wxConfigStorage;
|
|
||||||
long groupid = wxService.groupQueryUserGroup(configStorage.getOpenId());
|
|
||||||
Assert.assertTrue(groupid != -1l);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(dependsOnMethods={"testGroupGet", "testGroupCreate"})
|
@Test(dependsOnMethods={"testGroupGet", "testGroupCreate"})
|
||||||
public void getGroupUpdate() throws WxErrorException {
|
public void getGroupUpdate() throws WxErrorException {
|
||||||
group.setName("分组改名");
|
group.setName("分组改名");
|
||||||
wxService.groupUpdate(group);
|
wxService.groupUpdate(group);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(dependsOnMethods={"testGroupGet", "testGroupCreate"})
|
|
||||||
public void getGroupMoveUser() throws WxErrorException {
|
|
||||||
WxXmlConfigStorage configStorage = (WxXmlConfigStorage) wxService.wxConfigStorage;
|
|
||||||
wxService.userUpdateGroup(configStorage.getOpenId(), group.getId());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
package chanjarster.weixin.api;
|
package chanjarster.weixin.api;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -57,7 +58,8 @@ public class WxMediaAPITest {
|
|||||||
|
|
||||||
@Test(dependsOnMethods = { "testUploadMedia" }, dataProvider="downloadMedia")
|
@Test(dependsOnMethods = { "testUploadMedia" }, dataProvider="downloadMedia")
|
||||||
public void testDownloadMedia(String media_id) throws WxErrorException {
|
public void testDownloadMedia(String media_id) throws WxErrorException {
|
||||||
wxService.mediaDownload(media_id);
|
File file = wxService.mediaDownload(media_id);
|
||||||
|
Assert.assertNotNull(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
@DataProvider
|
@DataProvider
|
||||||
|
@@ -9,7 +9,7 @@ import chanjarster.weixin.exception.WxErrorException;
|
|||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 测试用户相关的接口
|
* 测试短连接
|
||||||
*
|
*
|
||||||
* @author chanjarster
|
* @author chanjarster
|
||||||
*/
|
*/
|
||||||
|
@@ -8,7 +8,6 @@ import chanjarster.weixin.api.ApiTestModule.WxXmlConfigStorage;
|
|||||||
import chanjarster.weixin.bean.result.WxUser;
|
import chanjarster.weixin.bean.result.WxUser;
|
||||||
import chanjarster.weixin.bean.result.WxUserList;
|
import chanjarster.weixin.bean.result.WxUserList;
|
||||||
import chanjarster.weixin.exception.WxErrorException;
|
import chanjarster.weixin.exception.WxErrorException;
|
||||||
import chanjarster.weixin.util.json.WxGsonBuilder;
|
|
||||||
|
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
|
|
||||||
@@ -17,7 +16,7 @@ import com.google.inject.Inject;
|
|||||||
* @author chanjarster
|
* @author chanjarster
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@Test(groups = "userAPI", dependsOnGroups = { "baseAPI" })
|
@Test(groups = "userAPI", dependsOnGroups = { "baseAPI", "groupAPI" })
|
||||||
@Guice(modules = ApiTestModule.class)
|
@Guice(modules = ApiTestModule.class)
|
||||||
public class WxUserAPITest {
|
public class WxUserAPITest {
|
||||||
|
|
||||||
@@ -33,7 +32,6 @@ public class WxUserAPITest {
|
|||||||
WxXmlConfigStorage configProvider = (WxXmlConfigStorage) wxService.wxConfigStorage;
|
WxXmlConfigStorage configProvider = (WxXmlConfigStorage) wxService.wxConfigStorage;
|
||||||
WxUser user = wxService.userInfo(configProvider.getOpenId(), null);
|
WxUser user = wxService.userInfo(configProvider.getOpenId(), null);
|
||||||
Assert.assertNotNull(user);
|
Assert.assertNotNull(user);
|
||||||
System.out.println(WxGsonBuilder.INSTANCE.create().toJson(user));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testUserList() throws WxErrorException {
|
public void testUserList() throws WxErrorException {
|
||||||
@@ -44,4 +42,15 @@ public class WxUserAPITest {
|
|||||||
Assert.assertFalse(wxUserList.getOpenids().size() == -1);
|
Assert.assertFalse(wxUserList.getOpenids().size() == -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testGroupQueryUserGroup() throws WxErrorException {
|
||||||
|
WxXmlConfigStorage configStorage = (WxXmlConfigStorage) wxService.wxConfigStorage;
|
||||||
|
long groupid = wxService.userGetGroup(configStorage.getOpenId());
|
||||||
|
Assert.assertTrue(groupid != -1l);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void getGroupMoveUser() throws WxErrorException {
|
||||||
|
WxXmlConfigStorage configStorage = (WxXmlConfigStorage) wxService.wxConfigStorage;
|
||||||
|
wxService.userUpdateGroup(configStorage.getOpenId(), wxService.groupGet().get(3).getId());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -6,13 +6,13 @@
|
|||||||
<class name="chanjarster.weixin.api.WxBaseAPITest" />
|
<class name="chanjarster.weixin.api.WxBaseAPITest" />
|
||||||
<class name="chanjarster.weixin.api.WxCustomMessageAPITest" />
|
<class name="chanjarster.weixin.api.WxCustomMessageAPITest" />
|
||||||
<class name="chanjarster.weixin.api.WxMenuAPITest" />
|
<class name="chanjarster.weixin.api.WxMenuAPITest" />
|
||||||
<class name="chanjarster.weixin.api.WxMessageRouterTest" />
|
<class name="chanjarster.weixin.api.WxGroupAPITest" />
|
||||||
<class name="chanjarster.weixin.api.WxMassMessageAPITest" />
|
<class name="chanjarster.weixin.api.WxMassMessageAPITest" />
|
||||||
<class name="chanjarster.weixin.api.WxMediaAPITest" />
|
<class name="chanjarster.weixin.api.WxMediaAPITest" />
|
||||||
<class name="chanjarster.weixin.api.WxMassMessageAPITest" />
|
|
||||||
<class name="chanjarster.weixin.api.WxUserAPITest" />
|
<class name="chanjarster.weixin.api.WxUserAPITest" />
|
||||||
<class name="chanjarster.weixin.api.WxQrCodeAPITest" />
|
<class name="chanjarster.weixin.api.WxQrCodeAPITest" />
|
||||||
<class name="chanjarster.weixin.api.WxShortUrlAPITest" />
|
<class name="chanjarster.weixin.api.WxShortUrlAPITest" />
|
||||||
|
<class name="chanjarster.weixin.api.WxMessageRouterTest" />
|
||||||
</classes>
|
</classes>
|
||||||
</test>
|
</test>
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user