|
|
@@ -318,8 +318,17 @@ class LsyOnboardingServiceTest {
|
|
|
Map<String, Object> info = service.merchantInfo(MCH_NO);
|
|
|
|
|
|
assertEquals("0.006", info.get("wx_channel_rate"), "字符串型费率必须原样带回");
|
|
|
- assertEquals("3", String.valueOf(info.get("merchant_type")),
|
|
|
- "数字型字段必须原样带回,被剔掉的话这里会是字符串 \"null\"");
|
|
|
+ // ★ 这里钉的是**运行时类型**,不是字符串化之后的值:`String.valueOf` 会把 Integer 3 与
|
|
|
+ // String "3" 抹平,于是「把所有值统一 stringify 再返回」这种实现照样绿 —— 而它正是
|
|
|
+ // 本条用例声称要抓的那类改动。类型**以实测为准**:真实解析器把 JSON 数字 3 解成
|
|
|
+ // java.lang.Integer(2026-09-22 实测:Integer 3 / wx_channel_rate=java.lang.String /
|
|
|
+ // 整个 map=java.util.LinkedHashMap);同一条用例里的 wx_channel_rate 当不了对照 ——
|
|
|
+ // 它的桩值本来就是 JSON 字符串,stringify 型实现在它上面是恒等变换。
|
|
|
+ Object merchantType = info.get("merchant_type");
|
|
|
+ assertEquals(Integer.valueOf(3), merchantType,
|
|
|
+ "数字型字段必须原样带回:JSON 数字 3 ⇒ Integer 3,既不能取成 String \"3\","
|
|
|
+ + "也不能被剔成 null。实际: " + merchantType
|
|
|
+ + (merchantType == null ? " (null)" : " (" + merchantType.getClass().getName() + ")"));
|
|
|
assertEquals(Set.of("result_code", "result_msg", "merchant_type", "wx_channel_rate"),
|
|
|
info.keySet(), "不得立白名单:上游给了什么键就带什么键,实际: " + info.keySet());
|
|
|
}
|
|
|
@@ -330,6 +339,10 @@ class LsyOnboardingServiceTest {
|
|
|
* <p>文案逐字取自 brief。brief 同一句里又说「照 {@code LsyMerchantService.requireByMchNo}
|
|
|
* 的口径」,而那个先例的文案其实是 {@code "mch_no 不能为空"} —— 两者不一致;
|
|
|
* 「照口径」指的是**空白检查 + 400 这个形状**,文案按 brief 的字面值走。
|
|
|
+ *
|
|
|
+ * <p>★ 这个字面值**不是新造的**:同类的 {@code LsyMerchantService.save}
|
|
|
+ * 抛的就是**逐字** {@code "商户号不能为空"}(实测 {@code LsyMerchantService.java:178})。
|
|
|
+ * 两句都在:{@code save} 与这里同字面,{@code requireByMchNo} 与这里不同字面。
|
|
|
*/
|
|
|
@Test
|
|
|
void merchantInfo_blankMchNo_throws400WithoutCallingUpstream() {
|