In our previous post, we discussed setting up Testing Library with a basic NextJS application. That’s all well and good, but we don’t use NextJS for basic applications. In fact, one of the main use cases of using NextJS is to create server-rendered applications.

Our goal with this tutorial is to explore testing NextJS applications that use serverless functions and server-side rendering.

Setting up our application

For the sake of brevity, let’s start with the same application we created in the last tutorial. You can clone it from Github. Next, let’s modify our application to use serverless functions and getServerSideProps.

Start by renaming /api/hello.js to dog.js. Fill it with the following

export const getDog = async () => {
	  const response = await fetch(url);
	  return await response.json();
	};

	const url = "https://dog.ceo/api/breeds/image/random";

	export default async (req, res) => {
	  try {
	    const dog = await getDog();
	    res.statusCode = 200;
	    res.json(dog);
	  } catch (e) {
	    res.statusCode = 500;
	    res.json({ status: "error" });
	  }
	};

You might notice that we didn’t install an additional dependency like node-fetch or isomorphic-fetch. That’s because NextJS 9.4 comes by default with a fetch polyfill. Neat!

In this function, we make a call to the Dog.ceo API to return a picture of a random dog.

Next, let’s modify our pages/index.js to make use of our new serverless function.

import { getDog } from "./api/dog";

	export default function Home(props) {
	  const [dog, setDog] = React.useState(props.initialDog);
	  const [loading, setLoading] = React.useState(false);
	  const fetchNewDog = async () => {
	    setLoading(true);
	    try {
	      const newDog = await getDog();
	      setDog(newDog);
	    } catch (e) {
	      setDog({ status: "error" });
	    } finally {
	      setLoading(false);
	    }
	  };

	  if (loading) {
	    return <div>Loading new dog...</div>;
	  }

	  return (
	    <div>
	      {dog.status !== "error" && <img src={dog.message} alt="a random dog" />}
	      {dog.status === "error" && <div>Error fetching dog</div>}
	      <button onClick={fetchNewDog}>Get new dog!</button>
	    </div>
	  );
	}

	export async function getServerSideProps() {
	  try {
	    const dog = await getDog();
	    return { props: { initialDog: dog } };
	  } catch (e) {
	    return {
	      props: {
	        initialDog: {
	          status: "error"
	        }
	      }
	    };
	  }
	}

Notice how we export a function called getServerSideProps. NextJS uses this function to prerender our page with the data returned by this function. But our users might get bored by always seeing the same dog, and they certainly don’t want to do a full page refresh to get a new dog.

#testing #programming #javascript #react #nodejs #nextjs

Testing getServerSideProps in NextJS
56.85 GEEK