Java Mockito停留在singleton方法的doReturn上

Java Mockito停留在singleton方法的doReturn上,java,input,mocking,jline,Java,Input,Mocking,Jline,我有一个singleton类来帮助我从控制台读取输入: public class IOHelper { public org.slf4j.Logger logger = Logger.logger; //JLine public ConsoleReader cr; private static IOHelper instance; private IOHelper(){ { try {

我有一个singleton类来帮助我从控制台读取输入:

public class IOHelper {
    public org.slf4j.Logger logger = Logger.logger;

    //JLine
    public ConsoleReader cr;

    private static IOHelper instance;

    private IOHelper(){
        {
            try {
                cr = new ConsoleReader();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static synchronized IOHelper getInstance(){
        if (instance == null){
            instance = new IOHelper();
        }

        return instance;
    }
我想测试的代码将其称为:

String in = IOHelper.getInstance().cr.readLine();
然后我的测试班:

class Test {

    private static NetworkCommunicator networkCommunicator;
    private static IOHelper ioHelper;

    @BeforeAll
    static void setUpClass() throws Throwable {

        ioHelper = spy(IOHelper.getInstance());
        doReturn("1").when(ioHelper).cr.readLine();

        networkCommunicator = spy(NetworkCommunicator.class);

        doNothing().when(networkCommunicator).connectToServer();
        doNothing().when(networkCommunicator).connectToOtherServer();
    }
我的测试卡在
doReturn(“1”).when(ioHelper).cr.readLine()上行,就好像它实际执行了
cr.readline()零件。我的stacktrace指向方法
private native int read0()抛出IOException。评论建议,如果没有可用的输入,它将被阻止。
我想替换控制台上的方法
readLine()
,这样当CLI请求输入时,我的测试可以“伪造”该输入

编辑:两个有趣线程的调用堆栈:

"main@1" prio=5 tid=0x1 nid=NA runnable
  java.lang.Thread.State: RUNNABLE
     blocks NonBlockingInputStreamThread@1437
      at java.io.FileInputStream.read0(FileInputStream.java:-1)
      at java.io.FileInputStream.read(FileInputStream.java:207)
      at jline.internal.NonBlockingInputStream.read(NonBlockingInputStream.java:166)
      - locked <0x67d> (a jline.internal.NonBlockingInputStream)
      at jline.internal.NonBlockingInputStream.read(NonBlockingInputStream.java:135)
      at jline.internal.NonBlockingInputStream.read(NonBlockingInputStream.java:243)
      at jline.internal.InputStreamReader.read(InputStreamReader.java:257)
      at jline.internal.InputStreamReader.read(InputStreamReader.java:194)
      at jline.console.ConsoleReader.readCharacter(ConsoleReader.java:2147)
      at jline.console.ConsoleReader.readCharacter(ConsoleReader.java:2137)
      at jline.console.ConsoleReader.readBinding(ConsoleReader.java:2222)
      at jline.console.ConsoleReader.readLine(ConsoleReader.java:2463)
      at jline.console.ConsoleReader.readLine(ConsoleReader.java:2374)
      at jline.console.ConsoleReader.readLine(ConsoleReader.java:2362)
      at jline.console.ConsoleReader.readLine(ConsoleReader.java:2350)
      at com.mypkg.Test.setUpClass(Test.java:43)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(NativeMethodAccessorImpl.java:-1)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      at java.lang.reflect.Method.invoke(Method.java:498)
      at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:389)
      at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:115)
      at org.junit.jupiter.engine.descriptor.ClassTestDescriptor.lambda$invokeBeforeAllMethods$5(ClassTestDescriptor.java:228)
      at org.junit.jupiter.engine.descriptor.ClassTestDescriptor$$Lambda$162.715378067.execute(Unknown Source:-1)
      at org.junit.jupiter.engine.execution.ThrowableCollector.execute(ThrowableCollector.java:40)
      at org.junit.jupiter.engine.descriptor.ClassTestDescriptor.invokeBeforeAllMethods(ClassTestDescriptor.java:227)
      at org.junit.jupiter.engine.descriptor.ClassTestDescriptor.before(ClassTestDescriptor.java:151)
      at org.junit.jupiter.engine.descriptor.ClassTestDescriptor.before(ClassTestDescriptor.java:61)
      at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.lambda$execute$3(HierarchicalTestExecutor.java:80)
      at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$$Lambda$134.398690014.execute(Unknown Source:-1)
      at org.junit.platform.engine.support.hierarchical.SingleTestExecutor.executeSafely(SingleTestExecutor.java:66)
      at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:77)
      at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.lambda$null$2(HierarchicalTestExecutor.java:92)
      at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$$Lambda$137.1353170030.accept(Unknown Source:-1)
      at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184)
      at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:175)
      at java.util.Iterator.forEachRemaining(Iterator.java:116)
      at java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801)
      at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
      at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
      at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151)
      at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174)
      at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
      at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:418)
      at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.lambda$execute$3(HierarchicalTestExecutor.java:92)
      at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$$Lambda$134.398690014.execute(Unknown Source:-1)
      at org.junit.platform.engine.support.hierarchical.SingleTestExecutor.executeSafely(SingleTestExecutor.java:66)
      at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:77)
      at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:51)
      at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:43)
      at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:170)
      at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:154)
      at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:90)
      at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:62)
      at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
      at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
      at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)

"NonBlockingInputStreamThread@1437" daemon prio=5 tid=0xf nid=NA waiting
  java.lang.Thread.State: WAITING
     waiting for main@1 to release lock on <0x67d> (a jline.internal.NonBlockingInputStream)
      at java.lang.Object.wait(Object.java:-1)
      at jline.internal.NonBlockingInputStream.run(NonBlockingInputStream.java:275)
      at java.lang.Thread.run(Thread.java:745)
”main@1“prio=5 tid=0x1 nid=NA可运行
java.lang.Thread.State:可运行
阻碍NonBlockingInputStreamThread@1437
位于java.io.FileInputStream.read0(FileInputStream.java:-1)
在java.io.FileInputStream.read(FileInputStream.java:207)处
位于jline.internal.NonBlockingInputStream.read(NonBlockingInputStream.java:166)
-锁定(一个jline.internal.NonBlockingInputStream)
位于jline.internal.NonBlockingInputStream.read(NonBlockingInputStream.java:135)
位于jline.internal.NonBlockingInputStream.read(NonBlockingInputStream.java:243)
位于jline.internal.InputStreamReader.read(InputStreamReader.java:257)
位于jline.internal.InputStreamReader.read(InputStreamReader.java:194)
位于jline.console.consolerereader.readCharacter(consolerereader.java:2147)
位于jline.console.consolerereader.readCharacter(consolerereader.java:2137)
位于jline.console.consolerereader.readBinding(consolerereader.java:2222)
位于jline.console.consolerereader.readLine(consolerereader.java:2463)
位于jline.console.consolerereader.readLine(consolerereader.java:2374)
位于jline.console.consolerereader.readLine(consolerereader.java:2362)
位于jline.console.consolerereader.readLine(consolerereader.java:2350)
位于com.mypkg.Test.setUpClass(Test.java:43)
在sun.reflect.NativeMethodAccessorImpl.invoke0处(NativeMethodAccessorImpl.java:-1)
位于sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)中
位于java.lang.reflect.Method.invoke(Method.java:498)
位于org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:389)
位于org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:115)
位于org.junit.jupiter.engine.descriptor.ClassTestDescriptor.lambda$invokeBeforeAllMethods$5(ClassTestDescriptor.java:228)
位于org.junit.jupiter.engine.descriptor.ClassTestDescriptor$$Lambda$162.715378067.execute(未知源:-1)
位于org.junit.jupiter.engine.execution.ThrowableCollector.execute(ThrowableCollector.java:40)
位于org.junit.jupiter.engine.descriptor.ClassTestDescriptor.invokeBeforeAllMethods(ClassTestDescriptor.java:227)
位于org.junit.jupiter.engine.descriptor.ClassTestDescriptor.before(ClassTestDescriptor.java:151)
位于org.junit.jupiter.engine.descriptor.ClassTestDescriptor.before(ClassTestDescriptor.java:61)
位于org.junit.platform.engine.support.hierarchy.HierarchycalTestExecutor.lambda$execute$3(HierarchycalTestExecutor.java:80)
位于org.junit.platform.engine.support.hierarchy.HierarchycalTestExecutor$$Lambda$134.398690014.execute(未知源:-1)
位于org.junit.platform.engine.support.hierarchy.SingleTestExecutor.ExecuteSafley(SingleTestExecutor.java:66)
位于org.junit.platform.engine.support.hierarchy.HierarchycalTestExecutor.execute(HierarchycalTestExecutor.java:77)
位于org.junit.platform.engine.support.hierarchy.HierarchycalTestExecutor.lambda$null$2(HierarchycalTestExecutor.java:92)
位于org.junit.platform.engine.support.hierarchy.HierarchycalTestExecutor$$Lambda$137.1353170030.accept(未知来源:-1)
位于java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184)
位于java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:175)
位于java.util.Iterator.ForEachLeving(Iterator.java:116)
位于java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801)
位于java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
位于java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
位于java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151)
位于java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174)
位于java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
位于java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:418)
位于org.junit.platform.engine.support.hierarchy.HierarchycalTestExecutor.lambda$execute$3(HierarchycalTestExecutor.java:92)
位于org.junit.platform.engine.support.hierarchy.HierarchycalTestExecutor$$Lambda$134.398690014.execute(未知源:-1)
位于org.junit.platform.engine.support.hierarchy.SingleTestExecutor.ExecuteSafley(SingleTestExecutor.java:66)
位于org.junit.platform.engine.support.hierarchy.HierarchycalTestExecutor.execute(HierarchycalTestExecutor.java:77)
位于org.junit.platform.engine.support.hierarchy.HierarchycalTestExecutor.execute(HierarchycalTestExecutor.java:51)
位于org.junit.platform.engine.support.hierarchy.HierarchycalTestEngine.execute(hierarchycalTestEngine.java:43)
位于org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:170)
位于org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:154)
位于org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:90)
位于com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:62)
在com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTes
private final IOHelper mySpy = spy(IOHelper.getInstance());

@Before
public void setup() {
    final ConsoleReader mockCR = mock(ConsoleReader.class);
    // Any mockery on your mockCR you need.
    // doReturn(...).when(mockCR).readLine();, etc.
    doReturn(mockCR).when(mySpy).getConsoleReader();
}
private final IOHelper ioHelper= IOHelper.getInstance();

@Before
public void setup() {
    final ConsoleReader mockCR = mock(ConsoleReader.class);
    // Any mockery on your mockCR you need.
    // doReturn(...).when(mockCR).readLine();, etc.
    ioHelper.cr = mockCR;
}
@RunWith(PowerMockRunner.class)
@PrepareForTest(IOHelper.class)
public class IOHelperTest {
    @BeforeClass
    public static void setup() {
        final ConsoleReader mockCR = mock(ConsoleReader.class);
        // Any mockery on your mockCR you need.
        // doReturn(...).when(mockCR).readLine();, etc.

        PowerMock.whenNew(ConsoleReader.class).thenReturn(mockCR);
    }
}