假设我们需要验证以下方法。
/**
* Prints {@code hello, world}, to the {@link System#out}, followed by a system dependent line separator.
*
* @param args command line arguments.
*/
public static void main(String... args) {
System.out.printf("hello, world%n"); // %n !!!!!!
}
现在我们可以验证该方法是否打印hello, world
。
/**
* Verifies that the {@link HelloWorld#main(String...)} method prints {@code hello, world}, to the
* {@link System#out}, followed by a system-dependent line separator.
*
* @author Jin Kwon <onacit_at_gmail.com>
* @see System#lineSeparator()
*/
@DisplayName("main(args) prints 'hello, world' followed by a system-dependent line separator")
@Test
public void main_PrintHelloWorld_() {
final var out = System.out;
try {
// --------------------------------------------------------------------------------------------------- given
final var buffer = new ByteArrayOutputStream();
System.setOut(new PrintStream(buffer));
// ---------------------------------------------------------------------------------------------------- when
HelloWorld.main();
// ---------------------------------------------------------------------------------------------------- then
final var actual = buffer.toByteArray();
final var expected = ("hello, world" + System.lineSeparator()).getBytes(StandardCharsets.US_ASCII);
Assertions.assertArrayEquals(actual, expected);
} finally {
System.setOut(out);
}
}
有疑问的部分是.getBytes(StandardCharsets.US_ASCII)
。
我认为,假设系统相关的行分隔符用 进行编码并没有错US_ASCII
。
Charset #defaultCharset()是否适合%n
?
您应该使用与对 返回的字节数组进行编码相同的编码
buffer.toByteArray()
。PrintStream
将字符串转换为字节是 的工作,那么您使用什么编码?PrintStream
您PrintStream
通过调用此构造函数创建了。文档说:因此您应该使用
Charset.defaultCharset()
将预期的字符串编码为字节数组。还可以考虑将自己的字符集传递
Charset
给PrintStream
使用此构造函数,并使用相同的字符集对预期的字符串进行编码。这样,您就可以非常清楚地知道您使用的是正确的字符集。