一.前言
关于这篇文章的起源,是在做一个小练习的时候,要求 TDD。真的是一个很小的练习,没有什么可测试的,那么我就想着要不测试下System.out
被调用了多少次吧。
二.代码
public class PrintlnCalled {
public static void main(String[] args) {
int[] arr = {1,2,3,4,5};
new PrintlnCalled().printArrayElement(arr);
}
public void printArrayElement(int[] arr) {
for (int i = 0; i < arr.length; i++) {
System.out.println("第"+ i + "个数:"+ arr[i]);
}
}
}
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import java.io.PrintStream;
import static org.mockito.Mockito.*;
public class PrintlnCalledTest {
@Mock
PrintStream mockedSystemOut;
// @InjectMocks
PrintlnCalled printlnCalled = new PrintlnCalled();
final private PrintStream systemOut = System.out;
@Before
public void setUp() throws Exception {
mockedSystemOut = mock(System.out.getClass());
//把输出流设为MOCK的对象
System.setOut(mockedSystemOut);
}
@Test
public void testPrintlnTimes() {
int[] arr = {1,2,3,4,5};
printlnCalled.printArrayElement(arr);
//验证MOCK对象的println()方法被调用的次数,此处用了Argument matchers : anyString()
verify(mockedSystemOut, times(5)).println(anyString());
}
@After
public void tearDown() throws Exception {
//测试结束,恢复输出流的默认值
System.setOut(systemOut);
}
}
测试结果符合预期
说明
为什么不用@InjectMocks
?
System.out
在java
中,不需要import
就可以使用,所以此处通过System.setOut(mockedSystemOut)
来代替了依赖注入,故而不需要在PrintlnCalled
类上面用@InjectMocks
了。
注意
改变了输出流,在测试结束后,一定要恢复输出流的默认测试,不然会影响正常的输出功能。
网友评论