2

Rails アプリケーションから圧縮された JSON 文字列を取得し、表現を返す前にデータを解凍する静的ヘルパー メソッドがありますString

私は 2 つの JUnit テストを作成しました。1 つは JSON が正しく解析されることをテストするテストで、もう 1 つは長さが 0 より大きい文字列がサーバーから返されるかどうかを判断する基本的なテストです。

問題:テスト スイートを実行すると、最初のテスト メソッドは正常に実行され、もう 1 つのテスト メソッドは失敗し、IOException「破損した GZIP トレーラー」というメッセージが表示されます (以下のコードを参照)。テストを逆の順序で実行すると、「成功した」テストが逆になるため、失敗しているのはテスト自体ではないと判断しました (つまり、何があっても失敗するのは常に 2 番目のテストです)。 2 つのテストのどちらが 2 番目に実行されても構いません)。

これはヘルパー メソッドです。

public static String doHTTPGet(String urlString) throws IOException{
    URL weatherAPI = new URL(urlString);
    HttpURLConnection apiConnection = (HttpURLConnection) weatherAPI.openConnection();
    apiConnection.setRequestMethod("GET");
    apiConnection.setRequestProperty("Accept-Encoding", "gzip");

    apiConnection.connect();

    BufferedInputStream bufferedInputStream = new BufferedInputStream(apiConnection.getInputStream());
    byte[] inputByteBuffer = new byte[10 * 1024];
    ByteArrayOutputStream outputStream = new ByteArrayOutputStream(10 * 1024); // initialize the output stream with at least one buffer's worth of bytes
    while(bufferedInputStream.read(inputByteBuffer)  > -1){
        outputStream.write(inputByteBuffer);
    }

    outputStream.close();
    bufferedInputStream.close();
    apiConnection.disconnect();

    ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(outputStream.toByteArray());
    byteArrayInputStream.close();

    GZIPInputStream gis = new GZIPInputStream(byteArrayInputStream);
    InputStreamReader inputStreamReader = new InputStreamReader(gis, "UTF-8");
    BufferedReader reader = new BufferedReader(inputStreamReader);

    String decompressedResponse = "";
    String line;

    // readLine() is generating the IOException on the second pass.
    while((line = reader.readLine()) != null){
        decompressedResponse += line;
    }

    reader.close();
    inputStreamReader.close();
    gis.close();

    return decompressedResponse;
}

エラーは、ヘルパー メソッドの下部の行で発生しますwhile((line = reader.readLine()) != null)...。具体的には、 でエラーが発生しますreader.readLine()

そして、2 つのテスト方法:

@Test
public void testHttpGet(){
    try {
        // FILTERED_API_URL_WITH_TOKEN is merely the URL with an auth token
        String apiResponse = HTTPHelper.doHTTPGet(GlobalConstants.FILTERED_API_URL_WITH_TOKEN);
        assertNotNull(apiResponse);
        assertTrue("The size of the API response should be greater than zero. It is an empty string.", apiResponse.length() > 0);
    } catch (IOException e) {
        e.printStackTrace();
        assertTrue("An exception occured while trying to perform the HTTP Get to the api at URL " + GlobalConstants.FILTERED_API_URL_WITH_TOKEN, false);
    }
}

@Test
public void testAPIContent(){
    try {
        // the getAPIJson() method basically does the same as the testHttpGet
        // method, but converts the string to a json
        JSONObject jsonObject = XMLProducerFromAPI.getAPIJson();
        System.out.println(jsonObject);
        assertNotNull(jsonObject);
    } catch (IOException e) {
        e.printStackTrace();
        assertTrue("An IOException occured. See stack trace", false);
    } catch (JSONException e) {
        e.printStackTrace();
        assertTrue("A JSONException occured. See stack trace", false);
    }
}

私はこの質問回答を読みましたが、それが当てはまるとは思いません(または、誤解している可能性があります。そうである場合はお知らせください)。彼らのアプローチを試してみましたが、同じメッセージしか受け取りませんでした。

メソッドは静的であり、作成されるオブジェクトはdoHTTPGetメソッドの本体内で行われるため、何も (ストリーム、接続オブジェクトなど) を再利用する必要はありません。率直に言って、私は困惑しています。

質問:「Corrupt GZIP Trailer」メッセージを生成するヘルパー コードで何か間違ったことをしたり、何らかのオブジェクトの使用方法を誤解したりしましたか? つまり、私のシナリオでこのエラーが発生する原因は何ですか?

いつものように、この質問に抜けているものがあれば教えてください。

編集

これはスタック トレースです。

java.io.IOException: Corrupt GZIP trailer
    at java.util.zip.GZIPInputStream.readTrailer(GZIPInputStream.java:200)
    at java.util.zip.GZIPInputStream.read(GZIPInputStream.java:92)
    at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:264)
    at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:306)
    at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:158)
    at java.io.InputStreamReader.read(InputStreamReader.java:167)
    at java.io.BufferedReader.fill(BufferedReader.java:136)
    at java.io.BufferedReader.readLine(BufferedReader.java:299)
    at java.io.BufferedReader.readLine(BufferedReader.java:362)
    at com.weathertx.xmlserver.support.HTTPHelper.doHTTPGet(HTTPHelper.java:60)
    at com.weathertx.xmlserver.tests.HttpHelperTest.getAPIResponse(HttpHelperTest.java:47)
    at com.weathertx.xmlserver.tests.HttpHelperTest.testHttpGet(HttpHelperTest.java:21)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
4

1 に答える 1