0

I have been trying to create a test with React, with the component TodoItems. It is just a regular Todolist with some basic features. When the test runs, it gives an error saying todos is undefined. The code in the test itself doesn't work as a result.

Test:

it("Tasks length increased by one when task is added.", () => {
  const { todos } = render(<TodoItems />);
  const todoLen = getByTestId(todos, "tasks");

  console.log(todos);
  expect(todoLen.toBe(1));
});

Component tested:

export default function Tasks() {
  let [tasks, setTasks] = useState([
    {
      content: "(Dette er en eksempelopppgave) "
    }
  ]);

  useEffect(() => {
    fetch("http://localhost:8080/all", {
      crossDomain: true,
      method: "GET",
      mode: "no-cors",
      credentials: "include"
    })
      .then(res => res.json())
      .then(function(response) {
        console.log("TodoItems is fetching.. ", response);
        if (response.status !== 200) {
          console.log("Fetching failed, response status: " + response.status);
          return;
        }
        response.json().then(function(data) {
          //was data instead of tasks, testing
          console.log(data, " is a response");
        });
      })
      .catch(function(err) {
        console.log("Fetch error: ", err);
      });
  }, []);

  // });

  let handleAddTask = task => {
    setTasks(tasks.concat(task));
    console.log("handleAddTask content: " + JSON.stringify(task));
  };

  let handleDeleteTask = id => {
    setTasks(tasks.filter(task => task.id !== id));
  };

  return (
    <div className="Tasks">
      <h2>Tasks</h2>
      <TaskList deleteTask={handleDeleteTask} tasks={tasks} />
      <TaskForm addTask={handleAddTask} />
      <Button onClick={reqListener}>Load</Button>
    </div>
  );
}

Edit(complete test code):

import React from "react";
import renderer from "react-test-renderer";
import TodoItems from "../components/TodoItems.js";
import { render, fireEvent, getByTestId } from "@testing-library/react";
import App from "../App.js";

//Test for the tasks array.
it("Tasks length increased by one when task is added.", () => {
  const { container, getByTestId } = render(<TodoItems />);
  const todos = getByTestId("tasks");

  expect(container).toBeDefined();
  expect(todos).toHaveLength(1);
});
4
  • You're rendering TodoItems but exported component's name is Tasks? Commented Nov 7, 2019 at 15:43
  • I thought when rendering TodoItems, it would automatically assume Tasks() was what we wanted? Commented Nov 7, 2019 at 15:47
  • Depends how you import it into your test file, also what framework are you using for rendering? Commented Nov 7, 2019 at 15:48
  • I am using this: import { render, fireEvent, getByTestId } from "@testing-library/react"; and import renderer from "react-test-renderer"; renderer is not in use however Commented Nov 7, 2019 at 15:52

1 Answer 1

1

When you're testing with the @testing-library/react, the render method returns container with a bunch of helpful getters, so you can do as follows:

it("Tasks length increased by one when task is added.", () => {
  const { container, getByTestId } = render(<TodoItems />);
  const todos = getByTestId("tasks"); 

  expect(container).toBeDefined();
  expect(todos).toHaveLength(1);
});

For the line const todos = getByTestId("tasks"); to work, you need to add data-testid attribute to your component:

 <TaskList deleteTask={handleDeleteTask} tasks={tasks} data-testid="tasks"/>
Sign up to request clarification or add additional context in comments.

1 Comment

I copied your code, and added the line in <TaskList>, but I get an error in the test: Unable to find an element by: [data-testid="tasks"]

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.