1

I'd like to display values from my JSON just for testing purposes, but I've received literally nothing. Where can be an issue? The link in Utils is correctly for sure, I've runned it on my browser, and everything was good.

Here's the code

Utils class

public class WeatherUtils {
public WeatherUtils(){}

public static ArrayList<Weather> getHourlyData (double minTemp, double maxTemp, double currentTemp, double airPressure){

    ArrayList<Weather> weatherList = new ArrayList<>();

    try {
        JSONObject reader = new JSONObject("https://api.openweathermap.org/data/2.5/forecast?q=London,us&units=metric&appid=ID...");
        JSONArray array = reader.getJSONArray("list");
        for (int i = 0; i<array.length(); i++){

            JSONObject secondReader = array.getJSONObject(i);
            JSONObject dataObject = secondReader.getJSONObject("main");
            for (int j = 0; j<dataObject.length(); j++){
                currentTemp = dataObject.getDouble("temp");
                minTemp = dataObject.getDouble("temp_min");
                maxTemp = dataObject.getDouble("temp_max");
                airPressure = dataObject.getDouble("pressure");
            }
            weatherList.add(new Weather(currentTemp,minTemp,maxTemp,airPressure));
        }

    } catch (JSONException e) {
        e.printStackTrace();
    }
    return weatherList;
 }
}

MainActivity Double a,b,c,d;

    a = 0.0;
    b = 0.0;
    c = 0.0;
    d = 0.0;

    ArrayList<Weather> weathers = WeatherUtils.getHourlyData(a,b,c,d);
    System.out.println(weathers);

JSON structure

 {
  "cod": "200",
  "message": 0.0074,
  "cnt": 40,
  "list": [
    {
      "dt": 1559131200,
      "main": {
        "temp": 22.1,
        "temp_min": 21.32,
        "temp_max": 22.1,
        "pressure": 1012.31,
        "sea_level": 1012.31,
        "grnd_level": 976.84,
        "humidity": 92,
        "temp_kf": 0.78
      },
      "weather": [
        {
          "id": 500,
          "main": "Rain",
          "description": "light rain",
          "icon": "10d"
        }
      ],
      "clouds": {
        "all": 89
      },
      "wind": {
        "speed": 3.08,
        "deg": 213.025
      },
      "rain": {
        "3h": 0.875
      },
      "sys": {
        "pod": "d"
      },
      "dt_txt": "2019-05-29 12:00:00"
    },
    {

Of course, there are more data. I've posted one "block"

How I may fix that?

  • 1
    what's the structure of json ? – Shiva Snape May 29 '19 at 13:43
  • Well you are not executing any http request on your example. If you want to mock data from testing purposes I would suggest mocking the json response by reading it directly from a raw resource. Also consider doing the request on a background thread. It seems like you are doing it on the main thread, which shouldn't be block otherwise you will get ANRs. – Javier Mendonça May 29 '19 at 13:43
  • 1
    I've edited a question. I want just test that, if I will receive something, if I do, I'll change the code to be more stability. –  May 29 '19 at 13:50

2 Answers2

0

Well, given that you just want to "test" the json parsing, you have few options but let's go with a simple one. But first, I would say to extract the parser and put it in its own class/method so it becomes easier to test, something like this:

public class WeatherUtils {
public WeatherUtils(){}

public static ArrayList<Weather> getHourlyData (double minTemp, double maxTemp, double currentTemp, double airPressure){

    final ArrayList<Weather> weatherList = new ArrayList<>();

    try {
        final JSONObject response = httpCall();
        weatherList = mapWeatherResponse(response);
    } catch (JSONException e) {
        e.printStackTrace();
    }
    return weatherList;
 }

public static List<Weather> mapWeatherResponse(JSONObject reader){
    final ArrayList<Weather> weatherList = new ArrayList<>();
    JSONArray array = reader.getJSONArray("list");
    for (int i = 0; i<array.length(); i++){
        JSONObject secondReader = array.getJSONObject(i);
        JSONObject dataObject = secondReader.getJSONObject("main");
        for (int j = 0; j<dataObject.length(); j++){
            currentTemp = dataObject.getDouble("temp");
            minTemp = dataObject.getDouble("temp_min");
            maxTemp = dataObject.getDouble("temp_max");
            airPressure = dataObject.getDouble("pressure");
        }
        weatherList.add(new Weather(currentTemp,minTemp,maxTemp,airPressure));
    }
}
}

Test the response parser with a junit test:

You can create a junit test like this:

public class WeatherUtilsTest {
    @Test
    public void parserResponseTEst() {
        final List<String> expectedResponse = new ArrayList<>();
        //fill the expectedResponse with the correspondent values

        final String json = "{\n" +
                "  \"cod\": \"200\",\n" +
                "  \"message\": 0.0074,\n" +
                "  \"cnt\": 40,\n" +
                "  \"list\": [\n" +
                "    {\n" +
                "      \"dt\": 1559131200,\n" +
                "      \"main\": {\n" +
                "        \"temp\": 22.1,\n" +
                "        \"temp_min\": 21.32,\n" +
                "        \"temp_max\": 22.1,\n" +
                "        \"pressure\": 1012.31,\n" +
                "        \"sea_level\": 1012.31,\n" +
                "        \"grnd_level\": 976.84,\n" +
                "        \"humidity\": 92,\n" +
                "        \"temp_kf\": 0.78\n" +
                "      },\n" +
                "      \"weather\": [\n" +
                "        {\n" +
                "          \"id\": 500,\n" +
                "          \"main\": \"Rain\",\n" +
                "          \"description\": \"light rain\",\n" +
                "          \"icon\": \"10d\"\n" +
                "        }\n" +
                "      ],\n" +
                "      \"clouds\": {\n" +
                "        \"all\": 89\n" +
                "      },\n" +
                "      \"wind\": {\n" +
                "        \"speed\": 3.08,\n" +
                "        \"deg\": 213.025\n" +
                "      },\n" +
                "      \"rain\": {\n" +
                "        \"3h\": 0.875\n" +
                "      }\n" +
                "    }]\n" +
                "    }";

        final List<String> response = WeatherUtils.mapWeatherResponse(new JSONObject(json));
        assertEquals(expectedResponse, response);
    }
}

There is nothing wrong with the JSONObject parser you are doing. You mentioned the link you are using in Utils is correct, do you get a proper response when you test it in your browser, postman, insomnia?

OBS JSONObject reader = new JSONObject("https://api..."); does not fetch anything, what you are doing there is creating a JSONObject from the given String, i.e. "https://....". To fetch the data you need to implement some http client. Here is an example https://stackoverflow.com/a/4457526/761668

Javier Mendonça
  • 1,970
  • 1
  • 17
  • 25
0

You're not getting the response from the server, you're trying to initialize a JSONObject with the URL.

To retrieve it you should replace this line:

JSONObject reader = new JSONObject("https://api.openweathermap.org/data/2.5/forecast?q=London,us&units=metric&appid=ID...");

with this code:

HttpURLConnection conn = null;
String data = null;
try {
   conn = (HttpURLConnection) new URL("https://api.openweathermap.org/data/2.5/forecast?q=London,us&units=metric&appid=ID...").openConnection();
   conn.setRequestMethod("GET");
   conn.connect();

   BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
   StringBuilder sb = new StringBuilder();
   String line;
   while ((line = br.readLine()) != null) {
      sb.append(line + "\n");
   }
   br.close();
   data = sb.toString();
} catch (Exception e) {
   // do something
} finally {
   if (conn != null) {
      try {
         conn.disconnect();
      } catch (Exception ex) {
         // do something
      }
   }
}

JSONObject reader = new JSONObject(data);

This code will retrieve the JSON object from the endpoint and convert it to a String object. Then you can create a JSONObject with it.

Jaime Suarez
  • 660
  • 4
  • 11