[英]How can I JUnit test “printlist”?
我已經盯着這段代碼已經有一段時間了,我真的不知道如何以及如何對其JUnit測試進行測試。
static void printList(OrderedIntList list) {
System.out.print("[");
for (int i = 0; i < list.orderedIntegerList.length; i++) {
System.out.print(list.orderedIntegerList[i]);
if (i != list.orderedIntegerList.length - 1) {
System.out.print(", ");
}
}
System.out.println("]");
}
這段代碼來自名為orderedIntList
的實用程序類,它是一個數組列表。
好吧...考慮這種方法的合同:它能保證什么? 它承諾將打印一個由逗號分隔並放在方括號內的整數列表。 因此,您可以在單元測試中指定它。
Edit2:以防萬一您想測試一下是否按順序打印列表:我不會認為這是printList
方法的屬性。 應該在修改OrderedIntList
的方法中測試此屬性。
用您希望打印的字符串為某些列表編寫一個燈具。 不要忘了極端情況:一個空列表。 然后,可能是大小為1的列表和大小為10的一個列表。
要檢查已打印的內容,可以創建一個新的PrintStream
,並通過調用System.setOut
設置System.out
的值。 在每次測試開始時都要執行此操作,並且不要忘記重置System.out
(因此請不要忘記存儲其原始值)。 您使用的PrintStream
不必花哨:您僅必須能夠比較打印的流。 您可能需要考慮使用Mockito 。
編輯:
例如,以下代碼測試包含唯一元素4
的列表是否實際打印字符串"[4]\\n"
:
@Test
public void aListOfSizeOneShouldPrintTheElementWithinBrackets() {
/* Setup */
final StringBuffer printStream = new StringBuffer();
PrintStream mockedOut = mock(PrintStream.class);
Mockito.doAnswer(new Answer() {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
printStream.append(invocation.getArguments()[0].toString());
return null;
}
}).when(mockedOut).print(any());
Mockito.doAnswer(new Answer() {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
printStream.append(invocation.getArguments()[0].toString());
return null;
}
}).when(mockedOut).print(anyString());
Mockito.doAnswer(new Answer() {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
printStream.append(invocation.getArguments()[0].toString()).append("\n");
return null;
}
}).when(mockedOut).println(any());
Mockito.doAnswer(new Answer() {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
printStream.append(invocation.getArguments()[0].toString()).append("\n");
return null;
}
}).when(mockedOut).println(anyString());
PrintStream originalOut = System.out;
System.setOut(mockedOut);
/* the actual test */
ArrayList<Integer> listWithOneElement = new ArrayList<Integer>();
listWithOneElement.add(4);
OrderedIntList list = new OrderedIntList(listWithOneElement);
OrderedIntList.printList(list);
MatcherAssert.assertThat(printStream.toString(), is("[4]\n"));
/* Teardown - reset System.out */
System.setOut(originalOut);
}
請注意,您可能想要提取setup-和拆解部分,以將其用於其他測試中並使測試可讀。 如果我沒有記錯的話,如果您使用@Before
和@After
注釋指定它,那么JUnit將提供添加在每次測試執行之前和之后調用的代碼的功能。
顯然,您不一定需要Mockito來實現此目的。 您還可以編寫一個實現PrintStream
並存儲打印字符串的類。 在這種情況下,Mockito僅允許您忽略所有不需要的方法(即,您不需要實現整個PrintStream
接口)
關於存根重復的小注釋:我們需要對兩個方法都進行存根,因為print
和println
都被使用了。 另外,由於覆蓋, print(String x)
與print(Object x)
,因此我們需要將它們都存根。
@Kulu Limpa的答案是正確的,但是比實際的實現要復雜得多,因為您需要一些模擬。
如果您將代碼重構為
static void printList(OrderedIntList list) {
System.out.println(toString(list));
}
static String toString(OrderedIntList list) {
StringBuilder result = new StringBuilder();
System.out.println(toString(list));
result.append("[");
for (int i = 0; i < list.orderedIntegerList.length; i++) {
result.append(list.orderedIntegerList[i]);
if (i != list.orderedIntegerList.length - 1) {
result.append(", ");
}
}
result.append("]");
return result.toString();
}
測試應該容易得多:
@Test
public void aListOfSizeOneShouldPrintTheElementWithinBrackets() {
ArrayList<Integer> listWithOneElement = new ArrayList<Integer>();
listWithOneElement.add(4);
OrderedIntList list = new OrderedIntList(listWithOneElement);
String result = OrderedIntList.toString(list);
MatcherAssert.assertThat(result, is("[4]"));
}
庫系統規則具有一個稱為StandardOutputStreamLog的JUnit規則。 使用此規則,您可以測試您的代碼,該代碼將寫入System.out
:
public void MyTest {
@Rule
public final StandardOutputStreamLog log = new StandardOutputStreamLog();
@Test
public void test() {
OrderedIntList list = ...
printList(list);
assertEquals("[1,2,3,4]", log.getLog());
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.