Using a local testnet allows you to control very precisely the state of the blockchain during your test. However, it will require you to deploy every contract you need manually.
A fork of the mainnet will save you from having to deploy every contract already deployed on the mainnet. However you will sacrifice control over the environment and will require a connection to a node.
I've deployed Uniswap 2V on a testnet a few times. To do it you will need the bytecode and ABI for the following contracts: UniswapV2Factory, UniswapV2Pair, UniswapV2Router02 (I suppose you want the second version of the router). The Uniswap docs explains very well how to download them from NPM. For the router to work properly you will also need to deploy a WETH contract. I suggest deploying the one from this github page.
Before running this code, just make sure that your chain is running. For hardhat run the following command:
npx hardhat node
Start by connecting your signer to your dev chain:
var provider = new ethers.providers.WebSocketProvider("ws://localhost:8545");
var signer = provider.getSigner();
Using the ethers.js library, you first deploy the factory:
const compiledUniswapFactory = require("@uniswap/v2-core/build/UniswapV2Factory.json");
var uniswapFactory = await new ethers.ContractFactory(compiledUniswapFactory.interface,compiledUniswapFactory.bytecode,signer).deploy(await signer.getAddress());
Then the WETH contract:
const compiledWETH = require("canonical-weth/build/conrtacts/WETH.json";
var WETH = await new ethers.ContractFactory(WETH.interface,WETH.bytecode,signer).deploy();
You can now deploy the router.
const compiledUniswapRouter = require("@uniswap/v2-periphery/build/UniswapV2Router02");
var router = await new ethers.ContractFactory(compiledUniswapRouter.abi,compiledUniswapRouter.bytecode,signer).deploy(uniswapFactory.address,WETH.address);
You will also need to deploy the ERC20 tokens you need (Here is an example with tokens I've written):
const compiledERC20 = require("../../../Ethereum/Ethereum/sources/ERC20.sol/Token.json");
var erc20Factory = new ethers.ContractFactory(compiledERC20.abi,compiledERC20.bytecode,signer);
var erc20_0 = await erc20Factory.deploy("1000000", "Token 0", "5", "T0");
var erc20_1 = await erc20Factory.deploy("1000000", "Token 1", "5", "T1");
The parameters of the deploy function will depend on the constructor of the token you wish to deploy.
You will also want to create pairs using the createPair method of the Uniswap factory.
uniswapFactory.createPair(erc20_0.address,erc20_1.address);
Keep in mind that in the pair the tokens will be ordered arbitrarly by the contract. ERC20_0 might not be the first of the two.
After that just wait for all the transactions to go through and you should be good to start your test.