缓冲 reader 测试
Buffered reader test
我想测试可以从特定 URL 地址获取数据并将其作为字符串添加到 ArrayList 的方法。现在的代码:
public List<String> getListOfAirportsFromCsvAsAStrings(String urlAddress) {
BufferedReader reader = null;
try {
URL url = new URL(urlAddress);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line = null;
while ((line = reader.readLine()) != null) {
airportsAsAStringFromCsvFile.add(line);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
return airportsAsAStringFromCsvFile;
}
这个方法可以测试吗?
照原样,该方法很难测试。正如标签所说,这显然不是以 TDD 方式完成的。
不要在被测代码中创建 HttpURLConnection。让调用者传递一个。这样你就可以在测试中轻松地模拟它并传递一些看起来像网络连接但不是真实的东西。将网络等外部依赖项排除在单元测试之外。在生产代码中,如果连接是在一个地方创建的,则可以轻松添加连接池或其他连接详细信息。
不要吞下异常。任何错误都不会被注意到。未来数小时的调试乐趣。您甚至无法测试错误行为。
airportsAsAStringFromCsvFile
是成员变量吗?它可能应该是一个局部变量,你可以使你的函数静态。
您可能还想尝试使用资源。
关于TDD书籍,你可以试试:
JUnit Recipes --- 很老了,但可能还有一些好的建议
这是无法正确进行单元测试的错误代码,单元测试是关于测试一些代码 "unit" 通常 class 孤立,如果此代码需要其他代码 classes要工作,您需要使用模拟 classes 而不是真正的实现。
在您的情况下,您应该将进入网络的代码与从流中读取的代码分离。
public class Parser {
public List<String> getListOfAirportsFromCsvAsAStrings(InputStream inputCsvData) {
List<String> airportsAsAStringFromCsvFile = new ArrayList<>();
try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputCsvData))) {
String line = null;
while ((line = reader.readLine()) != null) {
airportsAsAStringFromCsvFile.add(line);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
return airportsAsAStringFromCsvFile;
}
}
我简化了你的代码(需要 java 7 或更好)。这是对您的解析器的测试 class:
import example.Parser;
import org.junit.Assert;
import org.junit.Test;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;
public class ParserTest {
@Test
public void shouldReturnParsedTextFromInputFileStream() throws Exception {
String text = "row1\nrow2\nrow3";
InputStream inputFileStream = new ByteArrayInputStream(text.getBytes());
Parser parser = new Parser();
List<String> result = parser.getListOfAirportsFromCsvAsAStrings(inputFileStream);
List<String> expected = Arrays.asList("row1", "row2", "row3");
Assert.assertEquals(expected, result);
}
}
假设您的 class 路径中有 junit 库。
P.S。在我看来,这段代码仍然有味道,您需要更多地重构您的代码。
我想测试可以从特定 URL 地址获取数据并将其作为字符串添加到 ArrayList 的方法。现在的代码:
public List<String> getListOfAirportsFromCsvAsAStrings(String urlAddress) {
BufferedReader reader = null;
try {
URL url = new URL(urlAddress);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line = null;
while ((line = reader.readLine()) != null) {
airportsAsAStringFromCsvFile.add(line);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
return airportsAsAStringFromCsvFile;
}
这个方法可以测试吗?
照原样,该方法很难测试。正如标签所说,这显然不是以 TDD 方式完成的。
不要在被测代码中创建 HttpURLConnection。让调用者传递一个。这样你就可以在测试中轻松地模拟它并传递一些看起来像网络连接但不是真实的东西。将网络等外部依赖项排除在单元测试之外。在生产代码中,如果连接是在一个地方创建的,则可以轻松添加连接池或其他连接详细信息。
不要吞下异常。任何错误都不会被注意到。未来数小时的调试乐趣。您甚至无法测试错误行为。
airportsAsAStringFromCsvFile
是成员变量吗?它可能应该是一个局部变量,你可以使你的函数静态。
您可能还想尝试使用资源。
关于TDD书籍,你可以试试:
JUnit Recipes --- 很老了,但可能还有一些好的建议
这是无法正确进行单元测试的错误代码,单元测试是关于测试一些代码 "unit" 通常 class 孤立,如果此代码需要其他代码 classes要工作,您需要使用模拟 classes 而不是真正的实现。
在您的情况下,您应该将进入网络的代码与从流中读取的代码分离。
public class Parser {
public List<String> getListOfAirportsFromCsvAsAStrings(InputStream inputCsvData) {
List<String> airportsAsAStringFromCsvFile = new ArrayList<>();
try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputCsvData))) {
String line = null;
while ((line = reader.readLine()) != null) {
airportsAsAStringFromCsvFile.add(line);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
return airportsAsAStringFromCsvFile;
}
}
我简化了你的代码(需要 java 7 或更好)。这是对您的解析器的测试 class:
import example.Parser;
import org.junit.Assert;
import org.junit.Test;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;
public class ParserTest {
@Test
public void shouldReturnParsedTextFromInputFileStream() throws Exception {
String text = "row1\nrow2\nrow3";
InputStream inputFileStream = new ByteArrayInputStream(text.getBytes());
Parser parser = new Parser();
List<String> result = parser.getListOfAirportsFromCsvAsAStrings(inputFileStream);
List<String> expected = Arrays.asList("row1", "row2", "row3");
Assert.assertEquals(expected, result);
}
}
假设您的 class 路径中有 junit 库。 P.S。在我看来,这段代码仍然有味道,您需要更多地重构您的代码。