I have a smart contract that escrows and transfers a specific ERC20 token to and from users (with their approval). I'm a bit confused as to how to test transfers of existing tokens. Do I have to copy+paste the token contract into a dummy contract, migrate it, and use the deployed address in my contract? Or is there another feature of Truffle migrations and tests that I'm missing?
I assume you refer to testing on a public testnet? In which case a lot of tokens on there have a faucet to mint free tokens. (go to the project's website and change MetaMask to the testnet) Once you have the tokens, you can use them in your contract for testing.
If that doesn't exist or you talk about a local blockchain, then yeah you can just create an ERC-20 mock contract that allows you to mint free tokens. For any mainnet deployments you then have to use the real token address instead.
If you're looking to test locally (using for instance truffle and ganache) then see my answer here: https://ethereum.stackexchange.com/a/84015/3321