# Local testing using a Mock contract
Source: https://docs.chain.link/vrf/v2/subscription/examples/test-locally

> For the complete documentation index, see [llms.txt](/llms.txt).

> **TIP: VRF V2.5 Subscription Mock Tutorial**
>
> Refer to the [VRF V2.5 version of this subscription mock tutorial](/vrf/v2-5/subscription/test-locally) to learn how
> to test locally with VRF V2.5. To compare V2.5 and V2, refer to the [migration guide](/vrf/v2-5/migration-from-v2).

This guide explains how to test Chainlink VRF v2 on a [Remix IDE](https://remix-ide.readthedocs.io/en/latest/run.html#environment) sandbox blockchain environment. **Note**: You can reuse the same logic on another development environment, such as Hardhat or Truffle. For example, read the Hardhat Starter Kit [RandomNumberConsumer unit tests](https://github.com/smartcontractkit/hardhat-starter-kit/blob/main/test/unit/RandomNumberConsumer.spec.js).

> **CAUTION: Test on public testnets thoroughly**
>
> Even though local testing has several benefits, testing with a VRF mock covers the bare minimum of use cases. Make
> sure to test your consumer contract thoroughly on public testnets.

## Benefits of local testing

## Testing logic

Complete the following tasks to test your VRF v2 consumer locally:

1. Deploy the [VRFCoordinatorV2Mock](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/vrf/mocks/VRFCoordinatorV2Mock.sol). This contract is a mock of the [VRFCoordinatorV2](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/vrf/VRFCoordinatorV2.sol) contract.
2. Call the VRFCoordinatorV2Mock [createSubscription function](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/vrf/mocks/VRFCoordinatorV2Mock.sol#L194) to create a new subscription.
3. Call the VRFCoordinatorV2Mock [fundSubscription function](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/vrf/mocks/VRFCoordinatorV2Mock.sol#L156) to fund your newly created subscription. **Note**: You can fund with an arbitrary amount.
4. Deploy your VRF consumer contract.
5. Call the VRFCoordinatorV2Mock [addConsumer function](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/vrf/mocks/VRFCoordinatorV2Mock.sol#L230) to add your consumer contract to your subscription.
6. Request random words from your consumer contract.
7. Call the VRFCoordinatorV2Mock [fulfillRandomWords function](https://github.com/smartcontractkit/chainlink/blob/contracts-v1.3.0/contracts/src/v0.8/vrf/mocks/VRFCoordinatorV2Mock.sol#L108) to fulfill your consumer contract request.

## Testing

### Open the contracts on RemixIDE

Open *VRFCoordinatorV2Mock* and compile in Remix:

```sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;

import "@chainlink/contracts/src/v0.8/vrf/mocks/VRFCoordinatorV2Mock.sol";
```

Open *VRFv2Consumer* and compile in Remix:

```sol
// SPDX-License-Identifier: MIT
// An example of a consumer contract that relies on a subscription for funding.
pragma solidity ^0.8.7;

import {VRFConsumerBaseV2} from "@chainlink/contracts/src/v0.8/vrf/VRFConsumerBaseV2.sol";
import {VRFCoordinatorV2Interface} from "@chainlink/contracts/src/v0.8/vrf/interfaces/VRFCoordinatorV2Interface.sol";

/**
 * THIS IS AN EXAMPLE CONTRACT THAT USES HARDCODED VALUES FOR CLARITY.
 * THIS IS AN EXAMPLE CONTRACT THAT USES UN-AUDITED CODE.
 * DO NOT USE THIS CODE IN PRODUCTION.
 */

/**
 * @title The RandomNumberConsumerV2 contract
 * @notice A contract that gets random values from Chainlink VRF V2
 */
contract RandomNumberConsumerV2 is VRFConsumerBaseV2 {
  VRFCoordinatorV2Interface immutable COORDINATOR;

  // Your subscription ID.
  uint64 immutable s_subscriptionId;

  // The gas lane to use, which specifies the maximum gas price to bump to.
  // For a list of available gas lanes on each network,
  // see https://docs.chain.link/docs/vrf-contracts/#configurations
  bytes32 immutable s_keyHash;

  // Depends on the number of requested values that you want sent to the
  // fulfillRandomWords() function. Storing each word costs about 20,000 gas,
  // so 100,000 is a safe default for this example contract. Test and adjust
  // this limit based on the network that you select, the size of the request,
  // and the processing of the callback request in the fulfillRandomWords()
  // function.
  uint32 constant CALLBACK_GAS_LIMIT = 100_000;

  // The default is 3, but you can set this higher.
  uint16 constant REQUEST_CONFIRMATIONS = 3;

  // For this example, retrieve 2 random values in one request.
  // Cannot exceed VRFCoordinatorV2.MAX_NUM_WORDS.
  uint32 constant NUM_WORDS = 2;

  uint256[] public s_randomWords;
  uint256 public s_requestId;
  address s_owner;

  event ReturnedRandomness(uint256[] randomWords);

  /**
   * @notice Constructor inherits VRFConsumerBaseV2
   *
   * @param subscriptionId - the subscription ID that this contract uses for funding requests
   * @param vrfCoordinator - coordinator, check https://docs.chain.link/docs/vrf-contracts/#configurations
   * @param keyHash - the gas lane to use, which specifies the maximum gas price to bump to
   */
  constructor(
    uint64 subscriptionId,
    address vrfCoordinator,
    bytes32 keyHash
  ) VRFConsumerBaseV2(vrfCoordinator) {
    COORDINATOR = VRFCoordinatorV2Interface(vrfCoordinator);
    s_keyHash = keyHash;
    s_owner = msg.sender;
    s_subscriptionId = subscriptionId;
  }

  /**
   * @notice Requests randomness
   * Assumes the subscription is funded sufficiently; "Words" refers to unit of data in Computer Science
   */
  function requestRandomWords() external onlyOwner {
    // Will revert if subscription is not set and funded.
    s_requestId =
      COORDINATOR.requestRandomWords(s_keyHash, s_subscriptionId, REQUEST_CONFIRMATIONS, CALLBACK_GAS_LIMIT, NUM_WORDS);
  }

  /**
   * @notice Callback function used by VRF Coordinator
   *
   * @param  - id of the request
   * @param randomWords - array of random results from VRF Coordinator
   */
  function fulfillRandomWords(
    uint256,
    /* requestId */
    uint256[] memory randomWords
  ) internal override {
    s_randomWords = randomWords;
    emit ReturnedRandomness(randomWords);
  }

  modifier onlyOwner() {
    require(msg.sender == s_owner);
    _;
  }
}
```

Your RemixIDE file explorer should display *VRFCoordinatorV2Mock.sol* and *VRFv2Consumer.sol*:

(Image: Image)

### Deploy VRFCoordinatorV2Mock

1. Open *VRFCoordinatorV2Mock.sol*.

2. Under *DEPLOY & RUN TRANSACTIONS*, select *VRFCoordinatorV2Mock*.

   (Image: Image)

3. Under *DEPLOY*, fill in the `_BASEFEE` and `_GASPRICELINK`. These variables are used in the *VRFCoordinatorV2Mock* contract to represent the base fee and the gas price (in LINK tokens) for the VRF requests. You can set: `_BASEFEE=100000000000000000` and `_GASPRICELINK=1000000000`.

4. Click on *transact* to deploy the *VRFCoordinatorV2Mock* contract.

5. Once deployed, you should see the *VRFCoordinatorV2Mock* contract under *Deployed Contracts*.

   (Image: Image)

6. Note the address of the deployed contract.

### Create and fund a subscription

1. Click on `createSubscription` to create a new subscription.

2. In the RemixIDE console, read your transaction decoded output to find the subscription ID. In this example, the subscription ID is *1*.

   (Image: Image)

3. Click on `fundSubscription` to fund your subscription. In this example, you can set the `_subid` to `1` (which is your newly created subscription ID) and the `_amount` to `1000000000000000000`.

### Deploy the VRF consumer contract

1. In the file explorer, open *VRFv2Consumer.sol*.

2. Under *DEPLOY & RUN TRANSACTIONS*, select *RandomNumberConsumerV2*.

   (Image: Image)

3. Under *DEPLOY*, fill in `SUBSCRIPTIONID` with your subscription ID, `vrfCoordinator` with the deployed *VRFCoordinatorV2Mock* address and, *KEYHASH* with an arbitrary `bytes32` (In this example, you can set the *KEYHASH* to `0xd89b2bf150e3b9e13446986e571fb9cab24b13cea0a43ea20a6049a85cc807cc`).

4. Click on *transact* to deploy the *RandomNumberConsumerV2* contract.

5. After the consumer contract is deployed, you should see the *RandomNumberConsumerV2* contract under *Deployed Contracts*.

   (Image: Image)

6. Note the address of the deployed contract.

### Add the consumer contract to your subscription

1. Under *Deployed Contracts*, open the functions list of your deployed *VRFCoordinatorV2Mock* contract.

2. Click on *addConsumer* and fill in the `_subid` with your subscription ID and `_consumer` with your deployed consumer contract address.

   (Image: Image)

3. Click on *transact*.

### Request random words

1. Under *Deployed Contracts*, open the functions list of your deployed *RandomNumberConsumerV2* contract.

2. Click on `requestRandomWords`.

   (Image: Image)

3. In the RemixIDE console, read your transaction logs to find the VRF request ID. In this example, the request ID is *1*.

   (Image: Image)

4. Note your request ID.

### Fulfill the VRF request

Because you are testing on a local blockchain environment, you must fulfill the VRF request yourself.

1. Under *Deployed Contracts*, open the functions list of your deployed *VRFCoordinatorV2Mock* contract.

2. Click `fulfillRandomWords` and fill in `_requestId` with your VRF request ID and `_consumer` with your consumer contract address.

   (Image: Image)

3. Click on `transact`.

### Check the results

1. Under *Deployed Contracts*, open the functions list of your deployed *RandomNumberConsumerV2* contract.

2. Click on `s_requestId` to display the last request ID. In this example, the output is *1*.

   (Image: Image)

3. Each time you make a VRF request, your consumer contract requests two random words. After the request is fulfilled, the two random words are stored in the `s_randomWords` array. You can check the stored random words by reading the two first indexes of the `s_randomWords` array. To do so, click on the *s\_randomWords* function and:
   1. Fill in the index with *0* then click on *call* to read the first random word.

      {" "}

      (Image: Image)

   2. Fill in the index with *1* then click on *call* to read the second random word.

      {" "}

      (Image: Image)

## Next steps

This guide demonstrated how to test a VRF v2 consumer contract on your local blockchain. We made the guide on RemixIDE for learning purposes, but you can reuse the same [testing logic](#testing-logic) on another development environment, such as Truffle or Hardhat. For example, read the Hardhat Starter Kit [RandomNumberConsumer unit tests](https://github.com/smartcontractkit/hardhat-starter-kit/blob/main/test/unit/RandomNumberConsumer.spec.js).