Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you write Jest tests for getInitialProps?

static async getInitialProps({ query }) {
  let content;
  let alert;

  try {
    const first = query.first ? query.first : '';
    content = await getContent(first);
  } catch (error) {
    alert = 'There was an error loading data, please try again.';
    content = [];
  }

  return {
    content,
    alert,
  };
}

I'm trying to write tests for this logic but because it is server side code I'm struggling to understand how I write a test for it as it isn't available to me in instance().

Google hasn't shown me the way on this one so I'm wondering how others have tackled writing tests for getInitial props.

like image 451
Max Lynn Avatar asked Oct 21 '19 16:10

Max Lynn


People also ask

Where do I put jest tests?

Writing Jest integration tests. Jest integration test files always end in . test. js and should be located in the /tests folder.

Is jest enough for testing?

Jest is a JavaScript test runner that lets you access the DOM via jsdom . While jsdom is only an approximation of how the browser works, it is often good enough for testing React components.


1 Answers

First, take a look at what's a static method and what does the static keyword do.

Since getInitialProps is just a static function on a component, you can test it manually like any other function.

import MyComponent from "./path/to/MyComponent";

// Mock the getContent function which I don't know where it comes from.
jest.mock("../someModule.js", () => ({
  getContent: () => Promise.reject()
}));

describe("MyComponent", () => {
  it('populates the "alert" prop on getContent failure.', async () => {
    // Inject anything you want to test
    const props = await MyComponent.getInitialProps({
      query: { first: "whatever" }
    });

    // And make sure it results in what you want.
    expect(props).toEqual({
      content: [],
      alert: "There was an error loading data, please try again."
    });
  });
});

Most of the time, getInitialProps is called like that anyway.

export default class MyApp extends App {
  static async getInitialProps ({ Component, router, ctx }) {
    let pageProps = {}

    if (Component.getInitialProps) {
      pageProps = await Component.getInitialProps(ctx)
    }

    return { pageProps }
  }

The documentation describes getInitialProps goal and we can confirm that it's ok to call it directly and test its return value as an Object.

Notice that to load data when the page loads, we use getInitialProps which is an async static method. It can asynchronously fetch anything that resolves to a JavaScript plain Object, which populates props.

Data returned from getInitialProps is serialized when server rendering, similar to a JSON.stringify. Make sure the returned object from getInitialProps is a plain Object and not using Date, Map or Set.

For the initial page load, getInitialProps will execute on the server only. getInitialProps will only be executed on the client when navigating to a different route via the Link component or using the routing APIs.

like image 91
Emile Bergeron Avatar answered Oct 02 '22 07:10

Emile Bergeron