2017年10月25日水曜日

【Java】try with resourcesのカバレッジ

◆EclEmmaでどうしても通せないルートがある。
 各サイトが説明しているようにカバレッジに拘る必要はないのだが、
テスト漏れを即検出したいので、できれば100%にしたい。
しかし、下記のようにtry-with-resources 文など一部のコードがEclEmmaで全ルートパスできない。

ツールチップを表示すると7ルートミス。

Jmockit(下記コード参照)で1まで行くのだが、あと1ルートがパスできない。

◆テスト対象
package sampl.junitsample;

import java.io.IOException;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;

public class App {
 public static void main(String[] args) throws IOException {
  HttpURLConnection conn = (HttpURLConnection) new URL("http://localhost").openConnection();
  conn.setDoOutput(true);

  try (OutputStream st = conn.getOutputStream()) {
   st.write("abc".getBytes());
  }
 }
}

◆テストコード
package sampl.junitsample;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;

import org.junit.Test;

import mockit.Mock;
import mockit.MockUp;

public class AppTest {
 @Test
 public void testApp1() throws IOException {
  App.main(null);
 }

 @Test
 public void testApp2() throws IOException {
  new MockUp<sun.net.www.protocol.http.HttpURLConnection>() { // 何故かsun.~
   @Mock
   public OutputStream getOutputStream() throws IOException {
    throw new IOException("mock exception.");
   }
  };
  try {
   App.main(null);
  } catch (Exception e) {
   e.printStackTrace();
  }
 }

 @Test
 public void testApp3() throws IOException {
  new MockUp<java.io.ByteArrayOutputStream>() { // デバッガで実際の型を調べるとPosterOutputStream
   @Mock
   public void write(byte[] b) throws IOException {
    throw new IOException("mock exception.");
   }
  };
  try {
   App.main(null);
  } catch (Exception e) {
   e.printStackTrace();
  }
 }

 @Test
 public void testApp5() throws IOException {
  new MockUp<ByteArrayOutputStream>() { // デバッガで実際の型を調べるとPosterOutputStream
   @Mock
   public void write(byte[] b) throws IOException {
    throw new IOException("mock exception.");
   }

   @Mock
   public void close() throws IOException {
    throw new IOException("mock exception.");
   }
  };

  try {
   App.main(null);
  } catch (Exception e) {
   e.printStackTrace();
  }
 }

 @Test
 public void testApp6() throws IOException {
  new MockUp<sun.net.www.protocol.http.HttpURLConnection>() { // 何故かsun.~
   @Mock
   public OutputStream getOutputStream() throws IOException {
    return null;
   }
  };
  new MockUp<ByteArrayOutputStream>() {
   @Mock
   public void write(byte[] b) throws IOException {
    return;
   }

   @Mock
   public void close() throws IOException {
    throw new IOException("mock exception.");
   }
  };

  try {
   App.main(null);
  } catch (Exception e) {
   e.printStackTrace();
  }
 }
}

◆Maven(pom.xml)
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 <modelVersion>4.0.0</modelVersion>

 <groupId>sampl</groupId>
 <artifactId>junitsample</artifactId>
 <version>0.0.1-SNAPSHOT</version>
 <packaging>jar</packaging>

 <name>junitsample</name>
 <url>http://maven.apache.org</url>

 <properties>
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 </properties>

 <dependencies>
  <!-- https://mvnrepository.com/artifact/junit/junit -->
  <dependency>
   <groupId>junit</groupId>
   <artifactId>junit</artifactId>
   <version>4.4</version>
   <scope>test</scope>
  </dependency>
  <!-- https://mvnrepository.com/artifact/org.jmockit/jmockit -->
  <dependency>
   <groupId>org.jmockit</groupId>
   <artifactId>jmockit</artifactId>
   <version>1.35</version>
   <scope>test</scope>
  </dependency>
 </dependencies>

</project>

◆環境

  • Eclipse:4.7(pleiades)
  • EclEmma:3.0.0.201706140232