From 4b60768784404f27cc26371bb18d488f21f97658 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Tue, 6 Jan 2026 03:27:31 +0000
Subject: [PATCH 1/3] Initial plan
From 41a694c49e60613327e82f726da7199ff45d4a5e Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Tue, 6 Jan 2026 03:35:22 +0000
Subject: [PATCH 2/3] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20WxSignQueryResult=20?=
=?UTF-8?q?=E4=B8=AD=20contract=5Fexpired=5Ftime=20=E5=AD=97=E6=AE=B5?=
=?UTF-8?q?=E8=A7=A3=E6=9E=90=E9=94=99=E8=AF=AF?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: binarywang <1343140+binarywang@users.noreply.github.com>
---
.../wxpay/bean/result/WxSignQueryResult.java | 2 +-
.../bean/result/WxSignQueryResultTest.java | 110 ++++++++++++++++++
2 files changed, 111 insertions(+), 1 deletion(-)
create mode 100644 weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxSignQueryResultTest.java
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxSignQueryResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxSignQueryResult.java
index 524159719..af19aec60 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxSignQueryResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxSignQueryResult.java
@@ -112,7 +112,7 @@ protected void loadXml(Document d) {
contractDisplayAccount = readXmlString(d, "contract_display_account");
contractState = readXmlInteger(d, "contract_state");
contractSignedTime = readXmlString(d, "contract_signed_time");
- contractExpiredTime = readXmlString(d, "contrace_Expired_time");
+ contractExpiredTime = readXmlString(d, "contract_expired_time");
contractTerminatedTime = readXmlString(d, "contract_terminated_time");
contractTerminatedMode = readXmlInteger(d, "contract_termination_mode");
contractTerminationRemark = readXmlString(d, "contract_termination_remark");
diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxSignQueryResultTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxSignQueryResultTest.java
new file mode 100644
index 000000000..2391c0c92
--- /dev/null
+++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxSignQueryResultTest.java
@@ -0,0 +1,110 @@
+package com.github.binarywang.wxpay.bean.result;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+/**
+ * WxSignQueryResult 单元测试
+ *
+ * @author Binary Wang
+ */
+public class WxSignQueryResultTest {
+
+ /**
+ * 测试 XML 解析,特别是 contract_expired_time 字段
+ */
+ @Test
+ public void testFromXML() {
+ /*
+ * xml样例字符串来自于官方文档
+ * https://pay.weixin.qq.com/doc/v2/merchant/4011987640
+ */
+ String xmlString = "\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " 203\n" +
+ " 66\n" +
+ " \n" +
+ " 123\n" +
+ " \n" +
+ " \n" +
+ " 1\n" +
+ " 2015-07-01 10:00:00\n" +
+ " 2015-07-01 10:00:00\n" +
+ " 2015-07-01 10:00:00\n" +
+ " 3\n" +
+ " \n" +
+ " 0\n" +
+ " \n" +
+ " \n" +
+ "";
+
+ WxSignQueryResult result = WxSignQueryResult.fromXML(xmlString, WxSignQueryResult.class);
+
+ // 验证基本字段
+ Assert.assertEquals(result.getReturnCode(), "SUCCESS");
+ Assert.assertEquals(result.getResultCode(), "SUCCESS");
+ Assert.assertEquals(result.getMchId(), "80000000");
+ Assert.assertEquals(result.getAppid(), "wx426b3015555b46be");
+
+ // 验证签约相关字段
+ Assert.assertEquals(result.getContractId(), "203");
+ Assert.assertEquals(result.getPlanId(), "66");
+ Assert.assertEquals(result.getOpenId(), "oHZx6uMbIG46UXQ3SKxVYEgw1LZs");
+ Assert.assertEquals(result.getRequestSerial().longValue(), 123L);
+ Assert.assertEquals(result.getContractCode(), "1005");
+ Assert.assertEquals(result.getContractDisplayAccount(), "test");
+ Assert.assertEquals(result.getContractState().intValue(), 1);
+
+ // 重点测试时间字段,特别是 contract_expired_time
+ Assert.assertEquals(result.getContractSignedTime(), "2015-07-01 10:00:00");
+ Assert.assertEquals(result.getContractExpiredTime(), "2015-07-01 10:00:00");
+ Assert.assertEquals(result.getContractTerminatedTime(), "2015-07-01 10:00:00");
+
+ // 验证其他字段
+ Assert.assertEquals(result.getContractTerminatedMode().intValue(), 3);
+ Assert.assertEquals(result.getContractTerminationRemark(), "delete ....");
+ }
+
+ /**
+ * 测试 XML 解析 - 只包含必填字段
+ */
+ @Test
+ public void testFromXML_RequiredFieldsOnly() {
+ String xmlString = "\n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " \n" +
+ " Wx15463511252015071056489715\n" +
+ " 123\n" +
+ " 1695\n" +
+ " \n" +
+ " \n" +
+ " 0\n" +
+ " 2015-07-01 10:00:00\n" +
+ " 2016-07-01 10:00:00\n" +
+ " \n" +
+ " \n" +
+ "";
+
+ WxSignQueryResult result = WxSignQueryResult.fromXML(xmlString, WxSignQueryResult.class);
+
+ // 验证必填字段
+ Assert.assertEquals(result.getReturnCode(), "SUCCESS");
+ Assert.assertEquals(result.getResultCode(), "SUCCESS");
+ Assert.assertEquals(result.getContractId(), "Wx15463511252015071056489715");
+ Assert.assertEquals(result.getPlanId(), "123");
+ Assert.assertEquals(result.getContractState().intValue(), 0);
+
+ // 验证 contract_expired_time 字段能正确解析
+ Assert.assertEquals(result.getContractExpiredTime(), "2016-07-01 10:00:00");
+
+ // 验证非必填字段为 null
+ Assert.assertNull(result.getContractTerminatedTime());
+ Assert.assertNull(result.getContractTerminatedMode());
+ Assert.assertNull(result.getContractTerminationRemark());
+ }
+}
From 0b03dc260a79253555d8f9f9fe6cd9da9bc99d3f Mon Sep 17 00:00:00 2001
From: Binary Wang
Date: Tue, 6 Jan 2026 12:59:06 +0800
Subject: [PATCH 3/3] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=B5=8B=E8=AF=95?=
=?UTF-8?q?=EF=BC=9A=E5=90=AF=E7=94=A8=20fastMode=20=E4=BB=A5=E8=A6=86?=
=?UTF-8?q?=E7=9B=96=20WxSignQueryResult#loadXml=20=E5=88=86=E6=94=AF?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 在 testFromXML 和 testFromXML_RequiredFieldsOnly 测试方法中显式设置 XmlConfig.fastMode = true
- 使用 try-finally 块确保在测试后恢复 fastMode 的默认值
- 这样可以确保测试覆盖到 WxSignQueryResult#loadXml 方法中修复的 contract_expired_time 字段解析逻辑
---
.../bean/result/WxSignQueryResultTest.java | 87 +++++++++++--------
1 file changed, 51 insertions(+), 36 deletions(-)
diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxSignQueryResultTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxSignQueryResultTest.java
index 2391c0c92..52df2b6e2 100644
--- a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxSignQueryResultTest.java
+++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxSignQueryResultTest.java
@@ -1,5 +1,6 @@
package com.github.binarywang.wxpay.bean.result;
+import com.github.binarywang.wxpay.util.XmlConfig;
import org.testng.Assert;
import org.testng.annotations.Test;
@@ -41,31 +42,38 @@ public void testFromXML() {
" \n" +
"";
- WxSignQueryResult result = WxSignQueryResult.fromXML(xmlString, WxSignQueryResult.class);
+ // 启用 fastMode 以覆盖 WxSignQueryResult#loadXml 分支
+ XmlConfig.fastMode = true;
+ try {
+ WxSignQueryResult result = WxSignQueryResult.fromXML(xmlString, WxSignQueryResult.class);
- // 验证基本字段
- Assert.assertEquals(result.getReturnCode(), "SUCCESS");
- Assert.assertEquals(result.getResultCode(), "SUCCESS");
- Assert.assertEquals(result.getMchId(), "80000000");
- Assert.assertEquals(result.getAppid(), "wx426b3015555b46be");
+ // 验证基本字段
+ Assert.assertEquals(result.getReturnCode(), "SUCCESS");
+ Assert.assertEquals(result.getResultCode(), "SUCCESS");
+ Assert.assertEquals(result.getMchId(), "80000000");
+ Assert.assertEquals(result.getAppid(), "wx426b3015555b46be");
- // 验证签约相关字段
- Assert.assertEquals(result.getContractId(), "203");
- Assert.assertEquals(result.getPlanId(), "66");
- Assert.assertEquals(result.getOpenId(), "oHZx6uMbIG46UXQ3SKxVYEgw1LZs");
- Assert.assertEquals(result.getRequestSerial().longValue(), 123L);
- Assert.assertEquals(result.getContractCode(), "1005");
- Assert.assertEquals(result.getContractDisplayAccount(), "test");
- Assert.assertEquals(result.getContractState().intValue(), 1);
+ // 验证签约相关字段
+ Assert.assertEquals(result.getContractId(), "203");
+ Assert.assertEquals(result.getPlanId(), "66");
+ Assert.assertEquals(result.getOpenId(), "oHZx6uMbIG46UXQ3SKxVYEgw1LZs");
+ Assert.assertEquals(result.getRequestSerial().longValue(), 123L);
+ Assert.assertEquals(result.getContractCode(), "1005");
+ Assert.assertEquals(result.getContractDisplayAccount(), "test");
+ Assert.assertEquals(result.getContractState().intValue(), 1);
- // 重点测试时间字段,特别是 contract_expired_time
- Assert.assertEquals(result.getContractSignedTime(), "2015-07-01 10:00:00");
- Assert.assertEquals(result.getContractExpiredTime(), "2015-07-01 10:00:00");
- Assert.assertEquals(result.getContractTerminatedTime(), "2015-07-01 10:00:00");
+ // 重点测试时间字段,特别是 contract_expired_time
+ Assert.assertEquals(result.getContractSignedTime(), "2015-07-01 10:00:00");
+ Assert.assertEquals(result.getContractExpiredTime(), "2015-07-01 10:00:00");
+ Assert.assertEquals(result.getContractTerminatedTime(), "2015-07-01 10:00:00");
- // 验证其他字段
- Assert.assertEquals(result.getContractTerminatedMode().intValue(), 3);
- Assert.assertEquals(result.getContractTerminationRemark(), "delete ....");
+ // 验证其他字段
+ Assert.assertEquals(result.getContractTerminatedMode().intValue(), 3);
+ Assert.assertEquals(result.getContractTerminationRemark(), "delete ....");
+ } finally {
+ // 恢复默认值
+ XmlConfig.fastMode = false;
+ }
}
/**
@@ -90,21 +98,28 @@ public void testFromXML_RequiredFieldsOnly() {
" \n" +
"";
- WxSignQueryResult result = WxSignQueryResult.fromXML(xmlString, WxSignQueryResult.class);
+ // 启用 fastMode 以覆盖 WxSignQueryResult#loadXml 分支
+ XmlConfig.fastMode = true;
+ try {
+ WxSignQueryResult result = WxSignQueryResult.fromXML(xmlString, WxSignQueryResult.class);
- // 验证必填字段
- Assert.assertEquals(result.getReturnCode(), "SUCCESS");
- Assert.assertEquals(result.getResultCode(), "SUCCESS");
- Assert.assertEquals(result.getContractId(), "Wx15463511252015071056489715");
- Assert.assertEquals(result.getPlanId(), "123");
- Assert.assertEquals(result.getContractState().intValue(), 0);
-
- // 验证 contract_expired_time 字段能正确解析
- Assert.assertEquals(result.getContractExpiredTime(), "2016-07-01 10:00:00");
-
- // 验证非必填字段为 null
- Assert.assertNull(result.getContractTerminatedTime());
- Assert.assertNull(result.getContractTerminatedMode());
- Assert.assertNull(result.getContractTerminationRemark());
+ // 验证必填字段
+ Assert.assertEquals(result.getReturnCode(), "SUCCESS");
+ Assert.assertEquals(result.getResultCode(), "SUCCESS");
+ Assert.assertEquals(result.getContractId(), "Wx15463511252015071056489715");
+ Assert.assertEquals(result.getPlanId(), "123");
+ Assert.assertEquals(result.getContractState().intValue(), 0);
+
+ // 验证 contract_expired_time 字段能正确解析
+ Assert.assertEquals(result.getContractExpiredTime(), "2016-07-01 10:00:00");
+
+ // 验证非必填字段为 null
+ Assert.assertNull(result.getContractTerminatedTime());
+ Assert.assertNull(result.getContractTerminatedMode());
+ Assert.assertNull(result.getContractTerminationRemark());
+ } finally {
+ // 恢复默认值
+ XmlConfig.fastMode = false;
+ }
}
}