Mocking Browser Requests
The global fetch()
function is available in many JavaScript runtimes, including server-side runtimes and web browsers. While fetch()
works similarly in both environments, there are some important differences to take into account when testing code that uses fetch()
in a browser environment.
Relative URLs with fetch()
Perhaps the most significant difference between using fetch()
in a browser as opposed to a server environment is how relative URLs are handled. When you use fetch()
in a browser, relative URLs are resolved relative to the current page’s URL. This means that if you call fetch("/api/data")
from a page at https://example.com/page
, the request will be made to https://example.com/api/data
. This happens automatically in the browser whenever you use fetch()
, ensuring that requests go to the correct server.
If you try to use a relative URL with fetch()
in a server-side environment, you’ll get an error. This is because the server doesn’t know what the base URL should be, so it can’t resolve the relative URL. That means the same fetch()
call that works in the browser won’t work in a server environment and it’s important to keep that in mind when writing tests.
Mocking Browser Requests with Mentoss
Mentoss provides a way to mock browser requests in your tests, allowing you to test code that uses fetch()
without making actual network requests. To mock a browser request, you can provide a baseUrl
option to the FetchMocker
constructor. This option specifies the base URL that relative URLs should be resolved against. You can then call a mocked fetch()
using a relative URL. Here’s an example:
In this example, the baseUrl
option is set to "https://api.example.com"
, which means that relative URLs will be resolved against that base URL. The test then calls myFetch("/ping")
, which resolves to "https://api.example.com/ping"
and makes a request to the server. This allows you to test code that uses relative URLs with fetch()
in a browser-like environment.
Mocking CORS Requests
Another important consideration when mocking browser requests is how to handle CORS (Cross-Origin Resource Sharing) requests. CORS is a security feature that restricts which domains can make requests to a server. When you make a request from one domain to another, the server must include the appropriate CORS headers to allow the request to go through. When you set the baseUrl
option in the FetchMocker
constructor, Mentoss automatically includes the appropriate CORS headers when a request is made to a different origin.
Simple Requests
For simple requests, Mentoss automatically includes the Origin
header on the request. If the server responds with the appropriate Access-Control-Allow-Origin
header, your code will receive the response as expected. If the server does not respond with the appropriate header, the request will fail. Here’s an example:
In this example, the server responds with the Access-Control-Allow-Origin
header set to the base URL "https://api.example.com"
. This allows the request to go through because the origin matches the origin of the fetch mocker’s baseUrl
, and the test passes.
Preflighted Requests
For preflighted requests, Mentoss automatically sends an OPTIONS
request to the server to check if the request is allowed. If the server responds with the appropriate Access-Control-Allow-Methods
and Access-Control-Allow-Headers
headers, the original request will go through. If the server does not respond with the appropriate headers, the request will fail. Here’s an example:
In this example, the code attempts a request to "https://www.example.com/ping"
. Because this is a cross-origin request, Mentoss first sends an OPTIONS
request to the server to check if the request is allowed. The server responds to the preflight request with the appropriate Access-Control-Allow-Origin
and Access-Control-Allow-Headers
headers, allowing the original request to go through.
The Preflight Cache
When a browser makes a preflight request, it caches the response for a period of time (usually 5 minutes but customizable using the Access-Control-Max-Age
header). This means that if you make the same request again within the cache period, the browser won’t send another preflight request. Instead, it will use the cached response to determine if the request is allowed. Mentoss does not currently support caching preflight responses, so each preflight request will result in a new preflight request to the server.
Mentoss caches preflight responses in memory for the duration of the test run. This means that if you make the same preflighted request multiple times within a single test, Mentoss will only send the OPTIONS
request once. However, you can manually clear the preflight cache by calling the clearPreflightCache()
method. It’s helpful to do this after each test