Another suggestion (but it’s also good as-is):
 0--- a/src/rpc/rawtransaction.cpp
 1+++ b/src/rpc/rawtransaction.cpp
 2@@ -923,34 +923,36 @@ static UniValue testmempoolaccept(const JSONRPCRequest& request)
 3     result_0.pushKV("txid", tx_hash.GetHex());
 4 
 5     TxValidationState state;
 6-    bool test_accept_res;
 7+    bool allowed;
 8     CAmount fee{0}; // To return transaction fee from AcceptToMemoryPool
 9     {
10         LOCK(cs_main);
11-        test_accept_res = AcceptToMemoryPool(mempool, state, std::move(tx),
12+        allowed = AcceptToMemoryPool(mempool, state, std::move(tx),
13             nullptr /* plTxnReplaced */, false /* bypass_limits */, /* test_accept */ true, &fee);
14     }
15+    std::string reject_reason;
16 
17     // Check that fee does not exceed maxfee
18-    if (test_accept_res && max_raw_tx_fee && fee > max_raw_tx_fee) {
19-        result_0.pushKV("allowed", false);
20-        result_0.pushKV("reject-reason", "max-fee-exceeded");
21-        result.push_back(std::move(result_0));
22-        return result;
23+    if (allowed) {
24+        if (max_raw_tx_fee && fee > max_raw_tx_fee) {
25+            allowed = false;
26+            reject_reason = "max-fee-exceeded";
27         }
28-    result_0.pushKV("allowed", test_accept_res);
29-    if (!test_accept_res) {
30+    } else {
31         if (state.IsInvalid()) {
32             if (state.GetResult() == TxValidationResult::TX_MISSING_INPUTS) {
33-                result_0.pushKV("reject-reason", "missing-inputs");
34+                reject_reason = "missing-inputs";
35             } else {
36-                result_0.pushKV("reject-reason", strprintf("%s", state.GetRejectReason()));
37+                reject_reason = strprintf("%s", state.GetRejectReason());
38             }
39         } else {
40-            result_0.pushKV("reject-reason", state.GetRejectReason());
41+            reject_reason = state.GetRejectReason();
42         }
43     }
44-
45+    result_0.pushKV("allowed", allowed);
46+    if (!reject_reason.empty()) {
47+        result_0.pushKV("reject-reason", reject_reason);
48+    }
49     result.push_back(std::move(result_0));
50     return result;
51 }
 0    bool allowed;
 1    CAmount fee{0}; // To return transaction fee from AcceptToMemoryPool
 2    {
 3        LOCK(cs_main);
 4        allowed = AcceptToMemoryPool(mempool, state, std::move(tx),
 5            nullptr /* plTxnReplaced */, false /* bypass_limits */, /* test_accept */ true, &fee);
 6    }
 7    std::string reject_reason;
 8
 9    // Check that fee does not exceed maxfee
10    if (allowed) {
11        if (max_raw_tx_fee && fee > max_raw_tx_fee) {
12            allowed = false;
13            reject_reason = "max-fee-exceeded";
14        }
15    } else {
16        if (state.IsInvalid()) {
17            if (state.GetResult() == TxValidationResult::TX_MISSING_INPUTS) {
18                reject_reason = "missing-inputs";
19            } else {
20                reject_reason = strprintf("%s", state.GetRejectReason());
21            }
22        } else {
23            reject_reason = state.GetRejectReason();
24        }
25    }
26    result_0.pushKV("allowed", allowed);
27    if (!reject_reason.empty()) {
28        result_0.pushKV("reject-reason", reject_reason);
29    }
30    result.push_back(std::move(result_0));
31    return result;