Skip to content

test: 为覆盖率最低的 weixin-java-open、weixin-java-channel 补充单元测试 - #4080

Open
devin-ai-integration[bot] wants to merge 3 commits into
developfrom
devin/1785468833-add-unit-tests
Open

test: 为覆盖率最低的 weixin-java-open、weixin-java-channel 补充单元测试#4080
devin-ai-integration[bot] wants to merge 3 commits into
developfrom
devin/1785468833-add-unit-tests

Conversation

@devin-ai-integration

@devin-ai-integration devin-ai-integration Bot commented Jul 31, 2026

Copy link
Copy Markdown

Summary

统计各模块 src/main/javasrc/test/java 文件数后,测试占比最低的是 weixin-java-open(240 主类 / 13 测试)和 weixin-java-channel(674 / 36),且这两个模块已有测试几乎全是需要真实微信凭据的 *ServiceImplTest,本地不可执行。本 PR 新增不依赖网络与凭据的纯逻辑单元测试,并顺带修复由此暴露的一个既有反序列化 bug。

新增测试(15 个用例)

  • WxOpenCryptUtilTestencrypt → 解析 <Encrypt>/<MsgSignature>/<TimeStamp>/<Nonce>decryptXml/decryptContent 往返一致;签名不匹配抛 WxRuntimeExceptioncomponentAesKey 含空格时与去空格版本加密结果一致(覆盖构造函数中的 StringUtils.remove(encodingAesKey, " "))。
  • WxOpenXmlMessageTestfromXml 解析 component_verify_ticketauthorized、快速创建小程序推送(appid/status/auth_code/info.name,含 getRegistAppId() 兼容读取);fromXml(InputStream)fromEncryptedXml(String/InputStream) 往返并校验 context 为解密后的原始 xml。
  • WxOpenGsonBuilderTestcreate() 单例;WxOpenComponentAccessTokenWxOpenAuthorizerAccessTokenWxOpenAuthorizationInfo(含 func_info 缺失 funcscope_category 元素被跳过)、WxOpenQueryAuthResult 各适配器的反序列化;disableHtmlEscaping 行为。
  • XmlUtilsTest(channel):encodeencode(ObjectMapper, obj)decode(String/TypeReference/InputStream),以及未知字段被忽略、null/空串/非法 xml 返回 null 的容错分支。
  • WxChCryptUtilsTest(channel):回调消息加解密往返与签名校验失败分支;静态 decrypt(sessionKey, encryptedData, iv) 用本地 AES/CBC 加密数据做往返验证,以及非法密钥抛异常。

测试中的 token / EncodingAESKey 均为明显占位值(AES key 为 base64("0123456789abcdef" * 2) 去掉补位),不含任何真实凭据。

测试接入配置

两个模块的 Surefire 都显式指定 src/test/resources/testng.xml,因此在两个 suite 中新增 Util_Test 注册新增测试类;channel 侧顺带把此前未接入 suite 的 JsonUtilsTestResponseUtilsTest 一并加入,保证 mvn test 能真正执行。

修复 WxFastMaCanSetCategoryResult 的 errcode 字段冲突

接入 suite 后暴露既有测试 WxFastMaCanSetCategoryResultTest#testFromJson 失败:该 Bean 自带 @SerializedName("errcode") private int errCode,与父类 WxOpenResult#errcode 映射到同一 JSON 字段名,新版本 Gson 直接抛 IllegalArgumentException: declares multiple JSON fields named 'errcode',导致该结果类完全无法反序列化

-  @SerializedName("errcode")
-  private int errCode;
+  /** 已弃用,改用父类 WxOpenResult#getErrcode() */
+  @Deprecated
+  public int getErrCode() { return NumberUtils.toInt(this.errcode); }
+  @Deprecated
+  public void setErrCode(int errCode) { this.errcode = String.valueOf(errCode); }

移除重复字段,改为委托父类 errcode 的过时方法,保留 getErrCode()/setErrCode(int) 的源码兼容性;既有测试补充断言 getErrcode()=="0"getErrCode()==0isSuccess() 作为回归保护。

验证

pom.xml 中 surefire 配置为 <skip>true</skip>,默认不执行测试。验证时临时将其改为 false 运行,提交前已还原(diff 中不包含 pom.xml):

mvn -pl weixin-java-open test     # Tests run: 18, Failures: 0
mvn -pl weixin-java-channel test  # Tests run: 15, Failures: 0

本地环境为 JDK 17 + Maven 3.6.3;新增代码仅使用 Java 8 语法与 TestNG,遵循各模块既有测试风格。

Link to Devin session: https://app.devin.ai/sessions/14ac57aaa8c4438da6161b7ddb001650
Requested by: @binarywang

覆盖率最低的两个模块补充纯逻辑单元测试:
- open: WxOpenCryptUtil、WxOpenXmlMessage、WxOpenGsonBuilder 适配器
- channel: XmlUtils、WxChCryptUtils

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@binarywang binarywang self-assigned this Jul 31, 2026
@devin-ai-integration

Copy link
Copy Markdown
Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 40f45b483d

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

/**
* {@link WxOpenCryptUtil} 单元测试
*/
public class WxOpenCryptUtilTest {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 将 Open 新增单测加入 TestNG suite

weixin-java-open/pom.xml:122-124 中该模块固定通过 src/test/resources/testng.xml 运行 TestNG suite,Surefire 官方文档说明 suite 配置会覆盖默认扫描并运行 suite 文件中的测试(https://maven.apache.org/surefire-archives/surefire-3.5.4/maven-surefire-plugin/examples/testng.html#using-suite-xml-files);但当前 suite 只列出 3 个 bean.result 测试,没有包含这个类、WxOpenXmlMessageTestWxOpenGsonBuilderTest,所以启用常规 mvn -pl weixin-java-open -am test 时本 PR 新增的 Open 覆盖率不会执行。请把这些类加入 suite,或调整 Surefire 配置让默认扫描生效。

Useful? React with 👍 / 👎.

/**
* {@link WxChCryptUtils} 单元测试
*/
public class WxChCryptUtilsTest {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 将 Channel 新增单测加入 TestNG suite

weixin-java-channel/pom.xml:131-133 同样固定使用 src/test/resources/testng.xml,而该 suite 的 <classes>weixin-java-channel/src/test/resources/testng.xml:5-9 中没有任何启用的测试类;按 Surefire suite XML 语义(https://maven.apache.org/surefire-archives/surefire-3.5.4/maven-surefire-plugin/examples/testng.html#using-suite-xml-files),启用常规 mvn -pl weixin-java-channel -am test 时既不会执行这个类,也不会执行同 PR 新增的 XmlUtilsTest,导致新增 Channel 单测没有回归保护。请将新增类加入 suite,或移除 suiteXmlFiles 让默认扫描生效。

Useful? React with 👍 / 👎.

@binarywang binarywang left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

需要补充测试接入配置后再合并:

本 PR 新增的 5 个 TestNG 测试类没有加入 weixin-java-openweixin-java-channel 各自的 src/test/resources/testng.xml。两个模块的 Surefire 都显式指定该 suite;open 的 suite 只列出既有测试,channel 的 classes 为空,因此常规 mvn test / CI 不会执行这些新测试,无法形成持续回归保护。

请将新增测试类加入对应 suite(或调整 Surefire 配置为自动发现),并以模块测试命令验证它们确实被执行。

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@devin-ai-integration

Copy link
Copy Markdown
Author

需要补充测试接入配置后再合并

已修复(commit 75f347c):在两个模块的 src/test/resources/testng.xml 中新增 Util_Test,显式注册新增测试类;channel 侧顺带把此前未接入 suite 的 JsonUtilsTestResponseUtilsTest 一并加入。

验证(临时将根 pom.xml 的 surefire <skip> 改为 false 执行,验证后已还原,diff 不含 pom.xml):

  • mvn -pl weixin-java-channel test → Tests run: 15, Failures: 0
  • mvn -pl weixin-java-open test → Tests run: 18, Failures: 1

open 模块唯一失败的是既有测试 WxFastMaCanSetCategoryResultTest#testFromJson,与本 PR 无关,属历史问题:WxFastMaCanSetCategoryResult#errCode 与父类 WxOpenResult#errcode 在 Gson 下映射到同一字段名,新版 Gson 直接抛 IllegalArgumentException: declares multiple JSON fields named 'errcode'。本 PR 新增的 3 个 open 测试全部通过。是否需要我在本 PR 或单独 PR 中一并修复该 bean 的字段冲突?

…序列化异常

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@devin-ai-integration

Copy link
Copy Markdown
Author

已按确认修复 WxFastMaCanSetCategoryResulterrcode 字段冲突(commit 4e761a2):移除与父类 WxOpenResult#errcode 重名的 @SerializedName("errcode") private int errCode 字段,改为委托父类 errcode@Deprecated getErrCode() / setErrCode(int),保留源码兼容性;既有测试补充 getErrcode()getErrCode()isSuccess() 断言作为回归保护。

mvn -pl weixin-java-open test → Tests run: 18, Failures: 0(临时将根 pom surefire <skip> 置为 false 执行,已还原)。PR 描述已同步更新。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant