Skip to content

The blog style posts page from a previous lecture, used as a template for creating tests with react testing library

Notifications You must be signed in to change notification settings

CommandShiftHQ/Sept22-testing-in-react

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

13 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Testing in React lecture

This project was bootstrapped with Create React App. It is built on a demo repo used for the react intro 2 lecture, a simple blog style posts page built using useState, prop types and basic event handlers.

Here we will using Jest, React testing library and React test renderer to add tests that:

  • create snapshots
  • use valid props for test objects
  • fetch elements using queries
  • validate elements on screen using matchers
  • mock functions with Jest
  • validate functions are being called when triggering an event listener

Setup

Clone down the repo, and cd and into the new directory. If you want to start from the same place as we did at the start of the lecture, simply run npm i then npm start

If you want to see the finished app as it was at the end of the session, you will need to checkout the complete branch on this repo. You can do that by running

git checkout -t origin/complete

which will pull down the completed branch to your local environment (you will have to run npm i to update the new dependencies)

Starting point of app

Screenshot

Task list

App component:

  • Create a snapshot for the component
Solution
 test("Renders correctly", () => {
    const rendered = renderer.create(<App />)
    expect(rendered).toMatchSnapshot()
})

  • Assert the title text displayed within the component is correct
Solution
 test("Renders correct title", () => {
   render(<App />);
   const linkElement = screen.getByText("Testing in React", {exact: true});
   expect(linkElement).toBeInTheDocument();
 });

Post component:

In order to test the Post component we will need to mock the props it will take. Create a validProps object in your test file as follows:

const validProps = {
  postData: {
    author: "test author",
    body: "test body",
    date:"test date",
    isPublished: true,
    tags: ["test tag1", "test tag2", "test tag3"],
    title: "test title"
  },
  handleUpvote: jest.fn()
}
  • Create a snapshot
Solution
 test("Renders as expected" , () => {
   const rendered = renderer.create(
    <Post
        postData={validProps.postData}
        handleUpvote={validProps.handleUpvote}
    />)

    expect(rendered).toMatchSnapshot()
 })

  • Assert the post author is present
Solution
 test("Assert the post author is present", () => {
   render(
      <Post
        postData={validProps.postData}
        handleUpvote={validProps.handleUpvote}
      />);

    expect(screen.getByText("Author: test author")).toBeInTheDocument();
  })

  • Assert there is a single button and that it has the correct text
Solution
  test("Renders a single button with correct text", () => {
    render(
    <Post
        postData={validProps.postData}
        handleUpvote={validProps.handleUpvote}
    />
    );

    const buttons = screen.getAllByRole("button");

    expect(buttons).toHaveLength(1);
    expect(buttons[0]).toHaveTextContent("Upvote this")
  })

  • Assert the tags list has the correct number of items
Solution
  test("Tags list renders correct number of items", () => {
    render(
    <Post
        postData={validProps.postData}
        handleUpvote={validProps.handleUpvote}
    />
    );
    const tags = screen.getAllByRole("listitem");

    expect(tags.length).toBe(3);
  })

  • Assert clicking the button calls the handler function, and it has been called with the expected argument
Solution
  test("Upvote button calls correct function", () => {
    render(
    <Post
        postData={validProps.postData}
        handleUpvote={validProps.handleUpvote}
    />
    );
    fireEvent.click(screen.getByRole("button"));
    
    expect(validProps.handleUpvote).toHaveBeenCalled();
    expect(validProps.handleUpvote).toHaveBeenCalledTimes(1);
    expect(validProps.handleUpvote).toHaveBeenCalledWith(
    validProps.postData.title
    );
  })

PostList component:

Similarly to the Post component we will need to mock the props that the Postlist component will take. So will once again create a validProps object in your test file:

   const validProps = {
      posts: [
          {
              id: 1,
              author: "test author",
              body: "test body",
              date: "test date",
              isPublished: true,
              tags: ["test tag1", "test tag2", "test tag3"],
              title: "test title",
          },
          {
              id: 2,
              author: "test author 2",
              body: "test body 2",
              date: "test date 2",
              isPublished: false,
              tags: ["test tag1-2", "test tag2-2", "test tag3-2"],
              title: "test title 2",
          },
      ],
   };
  • Create a snapshot
Solution
  test("Renders as expected", () => {
    const rendered = renderer.create(<Postlist posts={validProps.posts} />)

    expect(rendered).toMatchSnapshot()
  })

  • Assert the 'last upvoted' field is updated when clicking on a post
Solution
  test("Last upvoted post is displayed when clicked", async () => {
    render(<Postlist posts={validProps.posts} />);

    const buttons = screen.getAllByRole("button");
    const firstPostUpvote = buttons[0];
    const secondPostUpvote = buttons[1];

    expect(firstPostUpvote).toHaveValue(validProps.posts[0].title);
    expect(secondPostUpvote).toHaveValue(validProps.posts[1].title);

    const lastUpvotedBox = screen.queryByText("Last upvoted post:");

    expect(lastUpvotedBox).toBeNull;

    fireEvent.click(firstPostUpvote);
    let lastUpvoted = await screen.findByText("Last upvoted post: test title");

    expect(lastUpvoted).toBeInTheDocument();

    fireEvent.click(secondPostUpvote);
    lastUpvoted = await screen.findByText("Last upvoted post: test title 2");

    expect(lastUpvoted).toBeInTheDocument();
  });

Available Scripts

Run the app with:

npm start

Open http://localhost:3000 to view it in your browser.

Run the tests with:

npm test

About

The blog style posts page from a previous lecture, used as a template for creating tests with react testing library

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published