***UPDATE:***

Turns out the issue was caused not by testnet, but by having 2 wallets @ryanofsky found out !

----------

Step to reproduce:

This work on regtest just fine:
```
bitcoind -wallet=test -regtest -rpcpassword=abc -rpcuser=abc
```

Try to make a batch RPC request to /wallet/test:

```
[{"jsonrpc":"1.0","id":1,"method":"getbalance","params":["*"]}]
```
You get the expected result.

However; same things with testnet:
```
bitcoind -wallet=test -testnet -rpcpassword=abc -rpcuser=abc
```

Result:

"Wallet file not specified (must request wallet RPC through /wallet/<filename> uri-path)."

This problem is limited to batched RPC request on testnet as just making the exact same request without the '[' and ']' works fine. It works also fine on regtest, which is crazy. I will look into later.
std::string strHash = vFields[2];
        static const unsigned int KEY_SIZE = 32;
        unsigned char out[KEY_SIZE];
        CHMAC_SHA256(reinterpret_cast<const unsigned char*>(strSalt.c_str()), strSalt.size()).Write(reinterpret_cast<const unsigned char*>(strPass.c_str()), strPass.size()).Finalize(out);
        std::vector<unsigned char> hexvec(out, out+KEY_SIZE);
        std::string strHashFromPass = HexStr(hexvec);
        if (TimingResistantEqual(strHashFromPass, strHash)) {
            return true;
        }
    }
    return false;
}
static bool RPCAuthorized(const std::string& strAuth, std::string& strAuthUsernameOut)
{
    if (strRPCUserColonPass.empty()) 
        return false;
    if (strAuth.substr(0, 6) != "Basic ")
        return false;
    std::string strUserPass64 = strAuth.substr(6);
    boost::trim(strUserPass64);
    std::string strUserPass = DecodeBase64(strUserPass64);
    if (strUserPass.find(":") != std::string::npos)
        strAuthUsernameOut = strUserPass.substr(0, strUserPass.find(":"));
    
    if (TimingResistantEqual(strUserPass, strRPCUserColonPass)) {
        return true;
    }
    return multiUserAuthorized(strUserPass);
}
static bool HTTPReq_JSONRPC(HTTPRequest* req, const std::string &)