title: ReactJS :: Jest Testing :: "TypeError: Cannot read property 'then' of undefined"
body: <p>I am currently having some trouble compiling a test for an online study task to see whether the fetch() function of my weather application is working correctly.</p>
  <p>I have made use of the useEffect() hook to fetch the data from the OpenWeather API to store and render once the API's URL changes.</p>
  <p>I am new to Jest testing and have tried a couple of things, following tutorials and other sources, but am unfortunately not having any success. My current solution is returning the following error: &quot;TypeError: Cannot read property 'then' of undefined&quot;</p>
  <p>Please see below my code:</p>
  <p><strong>App.js</strong></p>
  <pre><code>// Imported hooks and react libraries.
  import React, { useState, useEffect } from 'react';
  // Imported stylesheet.
  import './App.css';
  // Imported components.
  import Header from './components/Header';
  import Footer from './components/Footer';
  // Imported countries from i18n-iso-countries to get the iso code and return the country name in English.
  import countries from 'i18n-iso-countries';
  // Imported icons from Font Awesome.
  import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
  import {
    faCloudSunRain,
    faHandHoldingWater,
    faHandSparkles,
    faMapMarkerAlt,
    faSearchLocation,
    faTemperatureHigh,
    faTemperatureLow,
    faWind
  } from '@fortawesome/free-solid-svg-icons';
  
  countries.registerLocale(require('i18n-iso-countries/langs/en.json'));
  
  function App() {
    // Setting the initial states of the app to store the response and the locations. Using the useState hook to set the data. Showing Durban as 
    // an example.
    const [apiData, setApiData] = useState({});
    const [getState, setGetState] = useState('Durban');
    const [state, setState] = useState('Durban');
  
    // Constructing the API URL and accessing the key via the process.env variable.
    const apiKey = process.env.REACT_APP_API_KEY;
    const apiUrl = `https://api.openweathermap.org/data/2.5/weather?q=${state}&amp;APPID=${apiKey}`;
    console.log (process.env.REACT_APP_API_KEY);
  
    // Using the useEffect hook to fetch the data from the API to store and render once the API's URL changes.
    useEffect(() =&gt; {
      fetch(apiUrl)
        .then((res) =&gt; res.json())
        .then((data) =&gt; setApiData(data));
    }, [apiUrl]);
  
    // Constructed an input handler to get the data once requested and to store in the getState.
    const inputHandler = (event) =&gt; {
      setGetState(event.target.value);
    };
  
    // Constructed a submit handler to handle the request once the search button is clicked.
    const submitHandler = () =&gt; {
      setState(getState);
    };
  
    // Constructed a kelvin to celsius converter to output the temperature in celsius.
    const kelvinToCelsius = (k) =&gt; {
      return (k - 273.15).toFixed(2);
    };
  
    // Constructed a miles to kilometers converter to output the temperature in kilometers.
    const milesToKilometers = (k) =&gt; {
      return (k * 3.6).toFixed(2);
    };
  
    // Created a function to capitalize the first letters of each part of the countries' names.
    function capitalizeFirstLetter(string) {
      return string.charAt(0).toUpperCase() + string.slice(1);
    };
  
    // Returning the data. Included the React Bootstrap stylesheet's link and called the &quot;Header&quot; and &quot;Footer&quot; components below. I also called the
    // following from the API:
  
    // {apiData.weather[0].icon} - The icon displaying the current conditions.
    // {apiData.name} - The city's name.
    // {countries.getName(apiData.sys.country, 'en', { select: 'official', })} - The country's name with the first letters capitalized.
    // {kelvinToCelsius(apiData.main.temp_min)} - The minimum temperature.
    // {kelvinToCelsius(apiData.main.temp_max)} - The maximum temperature.
    // {kelvinToCelsius(apiData.main.feels_like)} - The &quot;feels like&quot; temperature, taking into account the temperatures and conditions.
    // {apiData.weather[0].main} - The summarized condition.
    // {capitalizeFirstLetter(apiData.weather[0].description)} - The full condition's description.
    // {apiData.main.humidity} - The humidity percentage.
    // {milesToKilometers(apiData.wind.speed)} - The wind speed.
  
    // Called the inputHandler (input section) and submitHandler (button) to get the current state's values and added Font Awesome icons. Also 
    // added a loading message for if the page load takes a while. Currently only shows if there is no input or upon refresh.
    return (
      &lt;div className=&quot;App&quot;&gt;
        &lt;link rel=&quot;stylesheet&quot; href=&quot;https://maxcdn.bootstrapcdn.com/bootstrap/latest/css/bootstrap.min.css&quot;&gt;&lt;/link&gt;
        &lt;Header /&gt;
  
        &lt;div className=&quot;container&quot;&gt;
          &lt;div className=&quot;searchsection&quot;&gt;
            &lt;label htmlFor=&quot;location-name&quot;&gt;Enter Location:&lt;/label&gt;
            &lt;input
              type=&quot;text&quot;
              id=&quot;location-name&quot;
              onChange={inputHandler}
              value={getState}
            /&gt;
            &lt;button onClick={submitHandler}&gt;&lt;FontAwesomeIcon icon={faSearchLocation} /&gt;&lt;/button&gt;
          &lt;/div&gt;
  
          &lt;div className=&quot;mt-3 mx-auto&quot; style={{ width: '60vw' }}&gt;
            {apiData.main ? (
              &lt;div id=&quot;weathercontainer&quot;&gt;
                &lt;div id=&quot;mainweather&quot;&gt;
                  &lt;img
                    src={`http://openweathermap.org/img/wn/${apiData.weather[0].icon}@2x.png`}
                    alt=&quot;weather status icon&quot;
                    className=&quot;weather-icon&quot;
                  /&gt;
                  &lt;p className=&quot;h2&quot;&gt;{kelvinToCelsius(apiData.main.temp)}&amp;deg;C&lt;/p&gt;
                  &lt;h3&gt;&lt;FontAwesomeIcon icon={faMapMarkerAlt} /&gt; {apiData.name}&lt;/h3&gt;
                  &lt;h3&gt;{countries.getName(apiData.sys.country, 'en', { select: 'official', })}&lt;/h3&gt;
                &lt;/div&gt;
  
                &lt;div className=&quot;temperatureconditions&quot;&gt;
                  &lt;div id=&quot;temperature&quot;&gt;
                    &lt;h5&gt;Temperature:&lt;/h5&gt;
                    &lt;p&gt;&lt;FontAwesomeIcon icon={faTemperatureLow} /&gt; {kelvinToCelsius(apiData.main.temp_min)}&amp;deg;C&lt;/p&gt;
                    &lt;p&gt;&lt;FontAwesomeIcon icon={faTemperatureHigh} /&gt; {kelvinToCelsius(apiData.main.temp_max)}&amp;deg;C&lt;/p&gt;
                    &lt;p&gt;&lt;FontAwesomeIcon icon={faHandSparkles} /&gt; Feels like: {kelvinToCelsius(apiData.main.feels_like)}&amp;deg;C&lt;/p&gt;
                  &lt;/div&gt;
                  &lt;div id=&quot;conditions&quot;&gt;
                    &lt;h5&gt;Conditions:&lt;/h5&gt;
                    &lt;p&gt;&lt;FontAwesomeIcon icon={faCloudSunRain} /&gt; {apiData.weather[0].main}: {capitalizeFirstLetter(apiData.weather[0].description)}&lt;/p&gt;
                    &lt;p&gt;&lt;FontAwesomeIcon icon={faHandHoldingWater} /&gt; Humidity: {apiData.main.humidity}%&lt;/p&gt;
                    &lt;p&gt;&lt;FontAwesomeIcon icon={faWind} /&gt; Wind Speed: {milesToKilometers(apiData.wind.speed)} km/h&lt;/p&gt;
                  &lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            ) : (
              &lt;h1 id=&quot;loading&quot;&gt;Weather Bot is Loading...&lt;/h1&gt;
            )}
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;Footer /&gt;
      &lt;/div&gt;
    );
  }
  
  // Exported App to Index.js.
  export default App;
  </code></pre>
  <p><strong>App.Fetch.React.test.js</strong></p>
  <pre><code>import React from 'react';
  import App from '../App';
  import { render, screen, act } from '@testing-library/react';
  
  global.fetch = jest.fn(() =&gt;
      Promise.resolve({
          json: () =&gt;
              Promise.resolve({
                  value: &quot;Durban&quot;
              }),
      })
  );
  
  describe(&quot;App&quot;, () =&gt; {
      it(&quot;loads Durban city name&quot;, async () =&gt; {
          await act(async () =&gt; render(&lt;App /&gt;));
          expect(screen.getByText(&quot;Durban&quot;)).toBeInTheDocument();
      });
  });
  </code></pre>
  <p>Does anyone mind helping?</p>